@haniffalab/cherita-react 1.2.0 → 1.3.0-dev.2025-05-29.ee7e9b72

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 (91) hide show
  1. package/dist/cjs/components/controls/Controls.js +60 -0
  2. package/dist/cjs/components/dotplot/Dotplot.js +47 -38
  3. package/dist/cjs/components/dotplot/DotplotControls.js +77 -114
  4. package/dist/cjs/components/full-page/FullPage.js +29 -33
  5. package/dist/cjs/components/full-page/FullPagePseudospatial.js +30 -33
  6. package/dist/cjs/components/heatmap/Heatmap.js +33 -22
  7. package/dist/cjs/components/heatmap/HeatmapControls.js +2 -19
  8. package/dist/cjs/components/matrixplot/Matrixplot.js +35 -24
  9. package/dist/cjs/components/matrixplot/MatrixplotControls.js +4 -34
  10. package/dist/cjs/components/obs-list/ObsItem.js +63 -51
  11. package/dist/cjs/components/obs-list/ObsList.js +53 -48
  12. package/dist/cjs/components/obsm-list/ObsmList.js +17 -12
  13. package/dist/cjs/components/offcanvas/index.js +14 -11
  14. package/dist/cjs/components/pseudospatial/Pseudospatial.js +78 -68
  15. package/dist/cjs/components/pseudospatial/PseudospatialToolbar.js +27 -21
  16. package/dist/cjs/components/scatterplot/Scatterplot.js +82 -76
  17. package/dist/cjs/components/scatterplot/ScatterplotControls.js +18 -31
  18. package/dist/cjs/components/scatterplot/SpatialControls.js +53 -23
  19. package/dist/cjs/components/scatterplot/Toolbox.js +1 -18
  20. package/dist/cjs/components/search-bar/SearchBar.js +156 -59
  21. package/dist/cjs/components/search-bar/SearchInfo.js +182 -0
  22. package/dist/cjs/components/search-bar/SearchResults.js +90 -60
  23. package/dist/cjs/components/var-list/VarItem.js +52 -75
  24. package/dist/cjs/components/var-list/VarList.js +47 -172
  25. package/dist/cjs/components/var-list/VarListToolbar.js +7 -8
  26. package/dist/cjs/components/var-list/VarSet.js +66 -57
  27. package/dist/cjs/components/violin/Violin.js +54 -43
  28. package/dist/cjs/components/violin/ViolinControls.js +4 -20
  29. package/dist/cjs/context/DatasetContext.js +26 -513
  30. package/dist/cjs/context/FilterContext.js +9 -8
  31. package/dist/cjs/context/SettingsContext.js +539 -0
  32. package/dist/cjs/context/ZarrDataContext.js +1 -2
  33. package/dist/cjs/helpers/color-helper.js +8 -8
  34. package/dist/cjs/helpers/zarr-helper.js +19 -16
  35. package/dist/cjs/utils/Filter.js +25 -21
  36. package/dist/cjs/utils/Histogram.js +4 -3
  37. package/dist/cjs/utils/ImageViewer.js +1 -2
  38. package/dist/cjs/utils/Legend.js +18 -12
  39. package/dist/cjs/utils/LoadingIndicators.js +1 -1
  40. package/dist/cjs/utils/VirtualizedList.js +16 -13
  41. package/dist/cjs/utils/errors.js +20 -22
  42. package/dist/cjs/utils/requests.js +13 -10
  43. package/dist/cjs/utils/zarrData.js +31 -50
  44. package/dist/css/cherita.css +84 -24
  45. package/dist/css/cherita.css.map +1 -1
  46. package/dist/esm/components/controls/Controls.js +51 -0
  47. package/dist/esm/components/dotplot/Dotplot.js +47 -37
  48. package/dist/esm/components/dotplot/DotplotControls.js +77 -112
  49. package/dist/esm/components/full-page/FullPage.js +29 -32
  50. package/dist/esm/components/full-page/FullPagePseudospatial.js +30 -32
  51. package/dist/esm/components/heatmap/Heatmap.js +32 -20
  52. package/dist/esm/components/heatmap/HeatmapControls.js +3 -20
  53. package/dist/esm/components/matrixplot/Matrixplot.js +34 -22
  54. package/dist/esm/components/matrixplot/MatrixplotControls.js +5 -35
  55. package/dist/esm/components/obs-list/ObsItem.js +63 -49
  56. package/dist/esm/components/obs-list/ObsList.js +53 -47
  57. package/dist/esm/components/obsm-list/ObsmList.js +17 -11
  58. package/dist/esm/components/offcanvas/index.js +14 -11
  59. package/dist/esm/components/pseudospatial/Pseudospatial.js +77 -66
  60. package/dist/esm/components/pseudospatial/PseudospatialToolbar.js +27 -20
  61. package/dist/esm/components/scatterplot/Scatterplot.js +81 -74
  62. package/dist/esm/components/scatterplot/ScatterplotControls.js +18 -29
  63. package/dist/esm/components/scatterplot/SpatialControls.js +54 -23
  64. package/dist/esm/components/scatterplot/Toolbox.js +1 -18
  65. package/dist/esm/components/search-bar/SearchBar.js +156 -59
  66. package/dist/esm/components/search-bar/SearchInfo.js +173 -0
  67. package/dist/esm/components/search-bar/SearchResults.js +91 -60
  68. package/dist/esm/components/var-list/VarItem.js +53 -76
  69. package/dist/esm/components/var-list/VarList.js +47 -171
  70. package/dist/esm/components/var-list/VarListToolbar.js +6 -6
  71. package/dist/esm/components/var-list/VarSet.js +67 -57
  72. package/dist/esm/components/violin/Violin.js +53 -41
  73. package/dist/esm/components/violin/ViolinControls.js +5 -21
  74. package/dist/esm/context/DatasetContext.js +25 -510
  75. package/dist/esm/context/FilterContext.js +8 -6
  76. package/dist/esm/context/SettingsContext.js +528 -0
  77. package/dist/esm/helpers/color-helper.js +8 -8
  78. package/dist/esm/helpers/zarr-helper.js +19 -16
  79. package/dist/esm/utils/Filter.js +25 -21
  80. package/dist/esm/utils/Histogram.js +4 -3
  81. package/dist/esm/utils/Legend.js +17 -10
  82. package/dist/esm/utils/LoadingIndicators.js +1 -1
  83. package/dist/esm/utils/VirtualizedList.js +15 -11
  84. package/dist/esm/utils/errors.js +20 -22
  85. package/dist/esm/utils/requests.js +13 -10
  86. package/dist/esm/utils/zarrData.js +33 -51
  87. package/package.json +6 -3
  88. package/scss/cherita.scss +50 -9
  89. package/scss/components/layouts.scss +24 -13
  90. package/scss/components/lists.scss +10 -0
  91. package/scss/components/plots.scss +3 -5
@@ -1,3 +1,8 @@
1
+ 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; }
2
+ 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; }
3
+ 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; }
4
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
5
+ 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); }
1
6
  import React, { useContext, useEffect, useMemo, useState } from "react";
2
7
  import { faChevronDown, faChevronRight } from "@fortawesome/free-solid-svg-icons";
3
8
  import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
@@ -11,7 +16,8 @@ import { useAccordionButton } from "react-bootstrap/AccordionButton";
11
16
  import AccordionContext from "react-bootstrap/AccordionContext";
12
17
  import { CategoricalObs, ContinuousObs } from "./ObsItem";
13
18
  import { COLOR_ENCODINGS, DEFAULT_OBS_GROUP, OBS_TYPES } from "../../constants/constants";
14
- import { useDataset, useDatasetDispatch } from "../../context/DatasetContext";
19
+ import { useDataset } from "../../context/DatasetContext";
20
+ import { useSettings, useSettingsDispatch } from "../../context/SettingsContext";
15
21
  import { LoadingSpinner } from "../../utils/LoadingIndicators";
16
22
  import { useFetch } from "../../utils/requests";
17
23
  const ObsAccordionToggle = _ref => {
@@ -28,7 +34,7 @@ const ObsAccordionToggle = _ref => {
28
34
  handleAccordionToggle(eventKey, isCurrentEventKey);
29
35
  });
30
36
  return /*#__PURE__*/React.createElement("div", {
31
- className: `obs-accordion-header ${isCurrentEventKey ? "active" : ""}`,
37
+ className: "obs-accordion-header ".concat(isCurrentEventKey ? "active" : ""),
32
38
  onClick: decoratedOnClick
33
39
  }, /*#__PURE__*/React.createElement("span", {
34
40
  className: "obs-accordion-header-chevron"
@@ -39,29 +45,32 @@ const ObsAccordionToggle = _ref => {
39
45
  }, children));
40
46
  };
41
47
  export function ObsColsList(_ref2) {
48
+ var _settings$selectedObs;
42
49
  let {
43
50
  showColor = true,
44
51
  enableObsGroups = true
45
52
  } = _ref2;
46
53
  const ENDPOINT = "obs/cols";
47
54
  const dataset = useDataset();
48
- const dispatch = useDatasetDispatch();
55
+ const settings = useSettings();
56
+ const dispatch = useSettingsDispatch();
49
57
  const [enableGroups, setEnableGroups] = useState(enableObsGroups);
50
58
  const [obsCols, setObsCols] = useState(null);
51
- const [active, setActive] = useState([...[dataset.selectedObs?.name]]);
59
+ const [active, setActive] = useState([...[(_settings$selectedObs = settings.selectedObs) === null || _settings$selectedObs === void 0 ? void 0 : _settings$selectedObs.name]]);
52
60
  const [params, setParams] = useState({
53
61
  url: dataset.url
54
62
  });
55
- const obsGroups = useMemo(() => ({
56
- default: _.union(DEFAULT_OBS_GROUP, dataset.obsGroups?.default),
57
- ..._.omit(dataset.obsGroups, "default")
58
- }), [dataset.obsGroups]);
63
+ const obsGroups = useMemo(() => {
64
+ var _dataset$obsGroups;
65
+ return _objectSpread({
66
+ default: _.union(DEFAULT_OBS_GROUP, (_dataset$obsGroups = dataset.obsGroups) === null || _dataset$obsGroups === void 0 ? void 0 : _dataset$obsGroups.default)
67
+ }, _.omit(dataset.obsGroups, "default"));
68
+ }, [dataset.obsGroups]);
59
69
  useEffect(() => {
60
70
  setParams(p => {
61
- return {
62
- ...p,
71
+ return _objectSpread(_objectSpread({}, p), {}, {
63
72
  url: dataset.url
64
- };
73
+ });
65
74
  });
66
75
  }, [dataset.url]);
67
76
  const {
@@ -82,7 +91,7 @@ export function ObsColsList(_ref2) {
82
91
  });
83
92
  if (!!filteredData.length && !groupFiltered.length) {
84
93
  setEnableGroups(false);
85
- console.warn(`No obs found in obsGroups ${JSON.stringify(obsGroups)}, disabling obsGroups`);
94
+ console.warn("No obs found in obsGroups ".concat(JSON.stringify(obsGroups), ", disabling obsGroups"));
86
95
  } else {
87
96
  filteredData = groupFiltered;
88
97
  }
@@ -93,17 +102,17 @@ export function ObsColsList(_ref2) {
93
102
  return d.type !== OBS_TYPES.DISCRETE;
94
103
  });
95
104
  setObsCols(_.keyBy(_.map(filteredData, d => {
96
- return {
97
- ...d,
105
+ return _objectSpread(_objectSpread({}, d), {}, {
98
106
  codesMap: _.invert(d.codes),
99
107
  omit: []
100
- };
108
+ });
101
109
  }), "name"));
102
110
  }
103
111
  }, [fetchedData, isPending, obsGroups, serverError, enableGroups]);
104
112
  useEffect(() => {
105
113
  if (obsCols) {
106
- if (!obsCols[dataset.selectedObs?.name]) {
114
+ var _settings$selectedObs2;
115
+ if (!obsCols[(_settings$selectedObs2 = settings.selectedObs) === null || _settings$selectedObs2 === void 0 ? void 0 : _settings$selectedObs2.name]) {
107
116
  setActive([]);
108
117
  dispatch({
109
118
  type: "select.obs",
@@ -111,7 +120,7 @@ export function ObsColsList(_ref2) {
111
120
  });
112
121
  }
113
122
  }
114
- }, [dataset.selectedObs, dispatch, obsCols]);
123
+ }, [settings.selectedObs, dispatch, obsCols]);
115
124
  const handleAccordionToggle = (itemName, isCurrentEventKey) => {
116
125
  if (isCurrentEventKey) {
117
126
  _.delay(() => setActive(prev => _.without(prev, itemName)), 250);
@@ -120,28 +129,26 @@ export function ObsColsList(_ref2) {
120
129
  }
121
130
  };
122
131
  const toggleAll = item => {
132
+ var _settings$selectedObs3;
123
133
  const omit = item.omit.length ? [] : _.map(item.values, v => item.codes[v]);
124
134
  setObsCols(o => {
125
- return {
126
- ...o,
127
- [item.name]: {
128
- ...item,
135
+ return _objectSpread(_objectSpread({}, o), {}, {
136
+ [item.name]: _objectSpread(_objectSpread({}, item), {}, {
129
137
  omit: omit
130
- }
131
- };
138
+ })
139
+ });
132
140
  });
133
- if (dataset.selectedObs?.name === item.name) {
141
+ if (((_settings$selectedObs3 = settings.selectedObs) === null || _settings$selectedObs3 === void 0 ? void 0 : _settings$selectedObs3.name) === item.name) {
134
142
  dispatch({
135
143
  type: "select.obs",
136
- obs: {
137
- ...item,
144
+ obs: _objectSpread(_objectSpread({}, item), {}, {
138
145
  omit: omit
139
- }
146
+ })
140
147
  });
141
148
  }
142
149
  };
143
150
  const toggleLabel = item => {
144
- const inLabelObs = _.some(dataset.labelObs, i => i.name === item.name);
151
+ const inLabelObs = _.some(settings.labelObs, i => i.name === item.name);
145
152
  if (inLabelObs) {
146
153
  dispatch({
147
154
  type: "remove.label.obs",
@@ -175,6 +182,7 @@ export function ObsColsList(_ref2) {
175
182
  });
176
183
  };
177
184
  const toggleObs = (item, value) => {
185
+ var _settings$selectedObs4;
178
186
  let omit;
179
187
  if (_.includes(item.omit, item.codes[value])) {
180
188
  omit = item.omit.filter(i => i !== item.codes[value]);
@@ -182,34 +190,32 @@ export function ObsColsList(_ref2) {
182
190
  omit = [...item.omit, item.codes[value]];
183
191
  }
184
192
  setObsCols(o => {
185
- return {
186
- ...o,
187
- [item.name]: {
188
- ...item,
193
+ return _objectSpread(_objectSpread({}, o), {}, {
194
+ [item.name]: _objectSpread(_objectSpread({}, item), {}, {
189
195
  omit: omit
190
- }
191
- };
196
+ })
197
+ });
192
198
  });
193
- if (dataset.selectedObs?.name === item.name) {
199
+ if (((_settings$selectedObs4 = settings.selectedObs) === null || _settings$selectedObs4 === void 0 ? void 0 : _settings$selectedObs4.name) === item.name) {
194
200
  dispatch({
195
201
  type: "select.obs",
196
- obs: {
197
- ...item,
202
+ obs: _objectSpread(_objectSpread({}, item), {}, {
198
203
  omit: omit
199
- }
204
+ })
200
205
  });
201
206
  }
202
207
  };
203
208
  const obsItem = item => {
209
+ var _settings$selectedObs5, _settings$selectedObs6;
204
210
  if (!item) {
205
211
  return null;
206
212
  }
207
213
  if (item.type === OBS_TYPES.DISCRETE) {
208
214
  return null;
209
215
  }
210
- const inLabelObs = _.some(dataset.labelObs, i => i.name === item.name);
211
- const inSliceObs = dataset.sliceBy.obs && dataset.selectedObs?.name === item.name;
212
- const isColorEncoding = dataset.colorEncoding === COLOR_ENCODINGS.OBS && dataset.selectedObs?.name === item.name;
216
+ const inLabelObs = _.some(settings.labelObs, i => i.name === item.name);
217
+ const inSliceObs = settings.sliceBy.obs && ((_settings$selectedObs5 = settings.selectedObs) === null || _settings$selectedObs5 === void 0 ? void 0 : _settings$selectedObs5.name) === item.name;
218
+ const isColorEncoding = settings.colorEncoding === COLOR_ENCODINGS.OBS && ((_settings$selectedObs6 = settings.selectedObs) === null || _settings$selectedObs6 === void 0 ? void 0 : _settings$selectedObs6.name) === item.name;
213
219
  return /*#__PURE__*/React.createElement("div", {
214
220
  className: "accordion-item",
215
221
  key: item.name
@@ -217,21 +223,21 @@ export function ObsColsList(_ref2) {
217
223
  eventKey: item.name,
218
224
  handleAccordionToggle: handleAccordionToggle
219
225
  }, /*#__PURE__*/React.createElement("div", null, item.name), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("span", {
220
- className: `mx-1 cursor-pointer ${inLabelObs ? "active-icon" : "text-muted opacity-50"}`,
226
+ className: "mx-1 cursor-pointer ".concat(inLabelObs ? "active-icon" : "text-muted opacity-50"),
221
227
  onClick: event => {
222
228
  event.stopPropagation();
223
229
  toggleLabel(item);
224
230
  },
225
231
  title: "Add to tooltip"
226
232
  }, /*#__PURE__*/React.createElement(CommentIcon, null)), /*#__PURE__*/React.createElement("span", {
227
- className: `mx-1 cursor-pointer ${inSliceObs ? "active-icon" : "text-muted opacity-50"}`,
233
+ className: "mx-1 cursor-pointer ".concat(inSliceObs ? "active-icon" : "text-muted opacity-50"),
228
234
  onClick: event => {
229
235
  event.stopPropagation();
230
236
  toggleSlice(item);
231
237
  },
232
238
  title: "Filter applied"
233
239
  }, /*#__PURE__*/React.createElement(JoinInnerIcon, null)), /*#__PURE__*/React.createElement("span", {
234
- className: `mx-1 cursor-pointer ${isColorEncoding ? "active-icon" : "text-muted opacity-50"}`,
240
+ className: "mx-1 cursor-pointer ".concat(isColorEncoding ? "active-icon" : "text-muted opacity-50"),
235
241
  onClick: event => {
236
242
  event.stopPropagation();
237
243
  toggleColor(item);
@@ -261,9 +267,9 @@ export function ObsColsList(_ref2) {
261
267
  })))));
262
268
  };
263
269
  const groupList = _.map(_.keys(obsGroups), group => {
264
- const key = `group-${group}`;
270
+ const key = "group-".concat(group);
265
271
  const groupItems = _.compact(_.map(_.sortBy(obsGroups[group], o => _.lowerCase(o.name)), item => {
266
- return obsItem(obsCols?.[item]);
272
+ return obsItem(obsCols === null || obsCols === void 0 ? void 0 : obsCols[item]);
267
273
  }));
268
274
  if (group === "default") {
269
275
  return groupItems;
@@ -280,7 +286,7 @@ export function ObsColsList(_ref2) {
280
286
  }
281
287
  });
282
288
  const obsList = enableGroups ? /*#__PURE__*/React.createElement(React.Fragment, null, groupList) : _.map(_.sortBy(obsCols, o => _.lowerCase(o.name)), item => obsItem(item));
283
- const defaultActiveGroup = enableGroups ? `group-${_.findKey(obsGroups, g => g.includes(active?.[0]))}` : null;
289
+ const defaultActiveGroup = enableGroups ? "group-".concat(_.findKey(obsGroups, g => g.includes(active === null || active === void 0 ? void 0 : active[0]))) : null;
284
290
  if (!serverError) {
285
291
  return /*#__PURE__*/React.createElement("div", {
286
292
  className: "position-relative h-100"
@@ -1,12 +1,19 @@
1
+ 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; }
2
+ 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; }
3
+ 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; }
4
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
5
+ 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); }
1
6
  import React, { useEffect, useState } from "react";
2
7
  import { Button, ButtonGroup, Dropdown, DropdownButton, OverlayTrigger, Tooltip } from "react-bootstrap";
3
- import { useDataset, useDatasetDispatch } from "../../context/DatasetContext";
8
+ import { useDataset } from "../../context/DatasetContext";
9
+ import { useSettings, useSettingsDispatch } from "../../context/SettingsContext";
4
10
  import { useFetch } from "../../utils/requests";
5
11
  import { ObsmKeysListBtn } from "../../utils/Skeleton";
6
12
  export function ObsmKeysList() {
7
13
  const ENDPOINT = "obsm/keys";
8
14
  const dataset = useDataset();
9
- const dispatch = useDatasetDispatch();
15
+ const settings = useSettings();
16
+ const dispatch = useSettingsDispatch();
10
17
  const [obsmKeysList, setObsmKeysList] = useState([]);
11
18
  const [active, setActive] = useState(null);
12
19
  const [params, setParams] = useState({
@@ -14,10 +21,9 @@ export function ObsmKeysList() {
14
21
  });
15
22
  useEffect(() => {
16
23
  setParams(p => {
17
- return {
18
- ...p,
24
+ return _objectSpread(_objectSpread({}, p), {}, {
19
25
  url: dataset.url
20
- };
26
+ });
21
27
  });
22
28
  }, [dataset.url]);
23
29
  const {
@@ -33,14 +39,14 @@ export function ObsmKeysList() {
33
39
  }
34
40
  }, [fetchedData, isPending, serverError]);
35
41
  useEffect(() => {
36
- if (dataset.selectedObsm) {
37
- setActive(dataset.selectedObsm);
42
+ if (settings.selectedObsm) {
43
+ setActive(settings.selectedObsm);
38
44
  }
39
- }, [dataset.selectedObsm]);
45
+ }, [settings.selectedObsm]);
40
46
  const obsmList = obsmKeysList.map(item => {
41
47
  return /*#__PURE__*/React.createElement(Dropdown.Item, {
42
48
  key: item,
43
- className: `custom ${active === item && "active"}`,
49
+ className: "custom ".concat(active === item && "active"),
44
50
  onClick: () => {
45
51
  dispatch({
46
52
  type: "select.obsm",
@@ -55,8 +61,8 @@ export function ObsmKeysList() {
55
61
  }
56
62
  return /*#__PURE__*/React.createElement(DropdownButton, {
57
63
  as: ButtonGroup,
58
- title: dataset.selectedObsm || "Select an embedding",
59
- variant: dataset.selectedObsm ? "primary" : "warning",
64
+ title: settings.selectedObsm || "Select an embedding",
65
+ variant: settings.selectedObsm ? "primary" : "warning",
60
66
  id: "bg-nested-dropdown",
61
67
  size: "sm"
62
68
  }, /*#__PURE__*/React.createElement(Dropdown.Header, null, "Embeddings"), obsmList);
@@ -1,3 +1,7 @@
1
+ const _excluded = ["show", "handleClose"],
2
+ _excluded2 = ["show", "handleClose", "Controls"];
3
+ function _objectWithoutProperties(e, t) { if (null == e) return {}; var o, r, i = _objectWithoutPropertiesLoose(e, t); if (Object.getOwnPropertySymbols) { var n = Object.getOwnPropertySymbols(e); for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]); } return i; }
4
+ 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; }
1
5
  import React from "react";
2
6
  import Offcanvas from "react-bootstrap/Offcanvas";
3
7
  import { SELECTION_MODES } from "../../constants/constants";
@@ -7,15 +11,14 @@ import { SearchBar } from "../search-bar/SearchBar";
7
11
  import { VarNamesList } from "../var-list/VarList";
8
12
  export function OffcanvasObs(_ref) {
9
13
  let {
10
- show,
11
- handleClose,
12
- ...props
13
- } = _ref;
14
+ show,
15
+ handleClose
16
+ } = _ref,
17
+ props = _objectWithoutProperties(_ref, _excluded);
14
18
  return /*#__PURE__*/React.createElement(Offcanvas, {
15
19
  show: show,
16
20
  onHide: handleClose,
17
- scroll: true,
18
- backdrop: false
21
+ scroll: true
19
22
  }, /*#__PURE__*/React.createElement(Offcanvas.Header, {
20
23
  closeButton: true
21
24
  }, /*#__PURE__*/React.createElement(Offcanvas.Title, null, "Categories")), /*#__PURE__*/React.createElement(Offcanvas.Body, {
@@ -53,11 +56,11 @@ export function OffcanvasVars(_ref3) {
53
56
  }
54
57
  export function OffcanvasControls(_ref4) {
55
58
  let {
56
- show,
57
- handleClose,
58
- Controls,
59
- ...props
60
- } = _ref4;
59
+ show,
60
+ handleClose,
61
+ Controls
62
+ } = _ref4,
63
+ props = _objectWithoutProperties(_ref4, _excluded2);
61
64
  return /*#__PURE__*/React.createElement(Offcanvas, {
62
65
  show: show,
63
66
  onHide: handleClose
@@ -1,3 +1,8 @@
1
+ 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; }
2
+ 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; }
3
+ 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; }
4
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
5
+ 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); }
1
6
  import React, { useCallback, useEffect, useMemo, useRef, useState } from "react";
2
7
  import { library } from "@fortawesome/fontawesome-svg-core";
3
8
  import { faSliders } from "@fortawesome/free-solid-svg-icons";
@@ -7,6 +12,7 @@ import Plot from "react-plotly.js";
7
12
  import { COLOR_ENCODINGS, OBS_TYPES, PSEUDOSPATIAL_PLOT_TYPES as PLOT_TYPES } from "../../constants/constants";
8
13
  import { useDataset } from "../../context/DatasetContext";
9
14
  import { useFilteredData } from "../../context/FilterContext";
15
+ import { useSettings } from "../../context/SettingsContext";
10
16
  import { rgbToHex, useColor } from "../../helpers/color-helper";
11
17
  import { ImageViewer } from "../../utils/ImageViewer";
12
18
  import { Legend } from "../../utils/Legend";
@@ -14,8 +20,10 @@ import { LoadingSpinner } from "../../utils/LoadingIndicators";
14
20
  import { useDebouncedFetch } from "../../utils/requests";
15
21
  library.add(faSliders);
16
22
  function usePseudospatialData(plotType) {
23
+ var _settings$selectedVar5, _settings$selectedVar6, _settings$selectedVar7, _settings$selectedVar8;
17
24
  const ENDPOINT = "pseudospatial";
18
25
  const dataset = useDataset();
26
+ const settings = useSettings();
19
27
  const {
20
28
  obsIndices,
21
29
  isSliced
@@ -23,50 +31,59 @@ function usePseudospatialData(plotType) {
23
31
  const baseParams = useMemo(() => {
24
32
  return {
25
33
  url: dataset.url,
26
- maskSet: dataset.pseudospatial.maskSet,
27
- maskValues: dataset.pseudospatial.maskValues,
34
+ maskSet: settings.pseudospatial.maskSet,
35
+ maskValues: settings.pseudospatial.maskValues,
28
36
  obsIndices: isSliced ? [...(obsIndices || [])] : null,
29
37
  varNamesCol: dataset.varNamesCol,
30
38
  showColorbar: false,
31
39
  format: "json"
32
40
  };
33
- }, [dataset.url, dataset.pseudospatial.maskSet, dataset.pseudospatial.maskValues, dataset.varNamesCol, isSliced, obsIndices]);
41
+ }, [dataset.url, settings.pseudospatial.maskSet, settings.pseudospatial.maskValues, dataset.varNamesCol, isSliced, obsIndices]);
34
42
  const getPlotParams = useCallback(() => {
35
43
  if (plotType === PLOT_TYPES.GENE) {
36
- return {
37
- varKey: dataset.selectedVar?.isSet ? {
38
- name: dataset.selectedVar?.name,
39
- indices: dataset.selectedVar?.vars.map(v => v.index)
40
- } : dataset.selectedVar?.index,
41
- ...(dataset.sliceBy.obs ? {
42
- obsCol: dataset.selectedObs,
43
- obsValues: !dataset.selectedObs?.omit.length ? null : _.difference(_.values(dataset.selectedObs?.codes), dataset.selectedObs?.omit).map(c => dataset.selectedObs?.codesMap[c])
44
- } : {})
45
- };
44
+ var _settings$selectedVar, _settings$selectedVar2, _settings$selectedVar3, _settings$selectedVar4, _settings$selectedObs, _settings$selectedObs2, _settings$selectedObs3;
45
+ return _objectSpread({
46
+ varKey: (_settings$selectedVar = settings.selectedVar) !== null && _settings$selectedVar !== void 0 && _settings$selectedVar.isSet ? {
47
+ name: (_settings$selectedVar2 = settings.selectedVar) === null || _settings$selectedVar2 === void 0 ? void 0 : _settings$selectedVar2.name,
48
+ indices: (_settings$selectedVar3 = settings.selectedVar) === null || _settings$selectedVar3 === void 0 ? void 0 : _settings$selectedVar3.vars.map(v => v.index)
49
+ } : (_settings$selectedVar4 = settings.selectedVar) === null || _settings$selectedVar4 === void 0 ? void 0 : _settings$selectedVar4.index
50
+ }, settings.sliceBy.obs ? {
51
+ obsCol: settings.selectedObs,
52
+ obsValues: !((_settings$selectedObs = settings.selectedObs) !== null && _settings$selectedObs !== void 0 && _settings$selectedObs.omit.length) ? null : _.difference(_.values((_settings$selectedObs2 = settings.selectedObs) === null || _settings$selectedObs2 === void 0 ? void 0 : _settings$selectedObs2.codes), (_settings$selectedObs3 = settings.selectedObs) === null || _settings$selectedObs3 === void 0 ? void 0 : _settings$selectedObs3.omit).map(c => {
53
+ var _settings$selectedObs4;
54
+ return (_settings$selectedObs4 = settings.selectedObs) === null || _settings$selectedObs4 === void 0 ? void 0 : _settings$selectedObs4.codesMap[c];
55
+ })
56
+ } : {});
46
57
  } else if (plotType === PLOT_TYPES.CATEGORICAL) {
58
+ var _settings$selectedObs5, _settings$selectedObs6, _settings$selectedObs7;
47
59
  return {
48
- obsCol: dataset.selectedObs,
49
- obsValues: !dataset.selectedObs?.omit.length ? null : _.difference(_.values(dataset.selectedObs?.codes), dataset.selectedObs?.omit).map(c => dataset.selectedObs?.codesMap[c]),
50
- mode: dataset.pseudospatial.categoricalMode
60
+ obsCol: settings.selectedObs,
61
+ obsValues: !((_settings$selectedObs5 = settings.selectedObs) !== null && _settings$selectedObs5 !== void 0 && _settings$selectedObs5.omit.length) ? null : _.difference(_.values((_settings$selectedObs6 = settings.selectedObs) === null || _settings$selectedObs6 === void 0 ? void 0 : _settings$selectedObs6.codes), (_settings$selectedObs7 = settings.selectedObs) === null || _settings$selectedObs7 === void 0 ? void 0 : _settings$selectedObs7.omit).map(c => {
62
+ var _settings$selectedObs8;
63
+ return (_settings$selectedObs8 = settings.selectedObs) === null || _settings$selectedObs8 === void 0 ? void 0 : _settings$selectedObs8.codesMap[c];
64
+ }),
65
+ mode: settings.pseudospatial.categoricalMode
51
66
  };
52
67
  } else if (plotType === "continuous") {
68
+ var _settings$selectedObs9, _settings$selectedObs0, _settings$selectedObs1;
53
69
  return {
54
- obsCol: dataset.selectedObs,
55
- obsValues: !dataset.selectedObs?.omit.length ? null : _.difference(_.values(dataset.selectedObs?.codes), dataset.selectedObs?.omit).map(c => dataset.selectedObs?.codesMap[c])
70
+ obsCol: settings.selectedObs,
71
+ obsValues: !((_settings$selectedObs9 = settings.selectedObs) !== null && _settings$selectedObs9 !== void 0 && _settings$selectedObs9.omit.length) ? null : _.difference(_.values((_settings$selectedObs0 = settings.selectedObs) === null || _settings$selectedObs0 === void 0 ? void 0 : _settings$selectedObs0.codes), (_settings$selectedObs1 = settings.selectedObs) === null || _settings$selectedObs1 === void 0 ? void 0 : _settings$selectedObs1.omit).map(c => {
72
+ var _settings$selectedObs10;
73
+ return (_settings$selectedObs10 = settings.selectedObs) === null || _settings$selectedObs10 === void 0 ? void 0 : _settings$selectedObs10.codesMap[c];
74
+ })
56
75
  };
57
76
  }
58
- }, [dataset.pseudospatial.categoricalMode, dataset.selectedObs, dataset.selectedVar?.index, dataset.selectedVar?.isSet, dataset.selectedVar?.name, dataset.selectedVar?.vars, dataset.sliceBy.obs, plotType]);
77
+ }, [settings.pseudospatial.categoricalMode, settings.selectedObs, (_settings$selectedVar5 = settings.selectedVar) === null || _settings$selectedVar5 === void 0 ? void 0 : _settings$selectedVar5.index, (_settings$selectedVar6 = settings.selectedVar) === null || _settings$selectedVar6 === void 0 ? void 0 : _settings$selectedVar6.isSet, (_settings$selectedVar7 = settings.selectedVar) === null || _settings$selectedVar7 === void 0 ? void 0 : _settings$selectedVar7.name, (_settings$selectedVar8 = settings.selectedVar) === null || _settings$selectedVar8 === void 0 ? void 0 : _settings$selectedVar8.vars, settings.sliceBy.obs, plotType]);
59
78
  const params = useMemo(() => {
60
- return {
61
- ...baseParams,
62
- ...getPlotParams()
63
- };
79
+ return _objectSpread(_objectSpread({}, baseParams), getPlotParams());
64
80
  }, [baseParams, getPlotParams]);
65
81
  return useDebouncedFetch(ENDPOINT + "/" + plotType, params, 500, {
66
- enabled: !!plotType && !!dataset.pseudospatial.maskSet
82
+ enabled: !!plotType && !!settings.pseudospatial.maskSet
67
83
  });
68
84
  }
69
85
  export function Pseudospatial(_ref) {
86
+ var _settings$selectedObs14, _layout$coloraxis3, _layout$coloraxis4;
70
87
  let {
71
88
  showLegend = true,
72
89
  sharedScaleRange = false,
@@ -75,29 +92,29 @@ export function Pseudospatial(_ref) {
75
92
  plotType,
76
93
  setPlotType
77
94
  } = _ref;
78
- const dataset = useDataset();
95
+ const settings = useSettings();
79
96
  const [data, setData] = useState([]);
80
97
  const [layout, setLayout] = useState({});
81
98
  const {
82
99
  getColor
83
100
  } = useColor();
84
- const colorscale = useRef(dataset.controls.colorScale);
101
+ const colorscale = useRef(settings.controls.colorScale);
85
102
  useEffect(() => {
86
- setPlotType(dataset.colorEncoding === COLOR_ENCODINGS.VAR ? PLOT_TYPES.GENE : dataset.selectedObs?.type === OBS_TYPES.CATEGORICAL || dataset.selectedObs?.type === OBS_TYPES.BOOLEAN ? PLOT_TYPES.CATEGORICAL : dataset.selectedObs?.type === OBS_TYPES.CONTINUOUS ? PLOT_TYPES.CONTINUOUS : PLOT_TYPES.MASKS);
87
- }, [dataset.colorEncoding, dataset.selectedObs?.type, setPlotType]);
103
+ var _settings$selectedObs11, _settings$selectedObs12, _settings$selectedObs13;
104
+ setPlotType(settings.colorEncoding === COLOR_ENCODINGS.VAR ? PLOT_TYPES.GENE : ((_settings$selectedObs11 = settings.selectedObs) === null || _settings$selectedObs11 === void 0 ? void 0 : _settings$selectedObs11.type) === OBS_TYPES.CATEGORICAL || ((_settings$selectedObs12 = settings.selectedObs) === null || _settings$selectedObs12 === void 0 ? void 0 : _settings$selectedObs12.type) === OBS_TYPES.BOOLEAN ? PLOT_TYPES.CATEGORICAL : ((_settings$selectedObs13 = settings.selectedObs) === null || _settings$selectedObs13 === void 0 ? void 0 : _settings$selectedObs13.type) === OBS_TYPES.CONTINUOUS ? PLOT_TYPES.CONTINUOUS : PLOT_TYPES.MASKS);
105
+ }, [settings.colorEncoding, (_settings$selectedObs14 = settings.selectedObs) === null || _settings$selectedObs14 === void 0 ? void 0 : _settings$selectedObs14.type, setPlotType]);
88
106
  const updateColorscale = useCallback(colorscale => {
89
107
  setLayout(l => {
90
- return {
91
- ...l,
92
- coloraxis: {
93
- ...l.coloraxis,
108
+ return _objectSpread(_objectSpread({}, l), {}, {
109
+ coloraxis: _objectSpread(_objectSpread({}, l.coloraxis), {}, {
94
110
  colorscale: colorscale
95
- }
96
- };
111
+ })
112
+ });
97
113
  });
98
114
  setData(d => {
99
- const min = layout?.coloraxis?.cmin;
100
- const max = layout?.coloraxis?.cmax;
115
+ var _layout$coloraxis, _layout$coloraxis2;
116
+ const min = layout === null || layout === void 0 || (_layout$coloraxis = layout.coloraxis) === null || _layout$coloraxis === void 0 ? void 0 : _layout$coloraxis.cmin;
117
+ const max = layout === null || layout === void 0 || (_layout$coloraxis2 = layout.coloraxis) === null || _layout$coloraxis2 === void 0 ? void 0 : _layout$coloraxis2.cmax;
101
118
  return _.map(d, trace => {
102
119
  const v = trace.meta.value;
103
120
  if (v === null) {
@@ -106,17 +123,15 @@ export function Pseudospatial(_ref) {
106
123
  const color = rgbToHex(getColor({
107
124
  value: (v - min) / (max - min)
108
125
  }));
109
- return {
110
- ...trace,
126
+ return _objectSpread(_objectSpread({}, trace), {}, {
111
127
  fillcolor: color,
112
- line: {
113
- ...trace.line,
128
+ line: _objectSpread(_objectSpread({}, trace.line), {}, {
114
129
  color: color
115
- }
116
- };
130
+ })
131
+ });
117
132
  });
118
133
  });
119
- }, [getColor, layout?.coloraxis?.cmax, layout?.coloraxis?.cmin]);
134
+ }, [getColor, layout === null || layout === void 0 || (_layout$coloraxis3 = layout.coloraxis) === null || _layout$coloraxis3 === void 0 ? void 0 : _layout$coloraxis3.cmax, layout === null || layout === void 0 || (_layout$coloraxis4 = layout.coloraxis) === null || _layout$coloraxis4 === void 0 ? void 0 : _layout$coloraxis4.cmin]);
120
135
  const {
121
136
  fetchedData,
122
137
  isPending,
@@ -130,17 +145,17 @@ export function Pseudospatial(_ref) {
130
145
  }
131
146
  }, [fetchedData, isPending, serverError, sharedScaleRange, updateColorscale]);
132
147
  useEffect(() => {
133
- colorscale.current = dataset.controls.colorScale;
148
+ colorscale.current = settings.controls.colorScale;
134
149
  updateColorscale(colorscale.current);
135
- }, [dataset.controls.colorScale, updateColorscale]);
150
+ }, [settings.controls.colorScale, updateColorscale]);
136
151
  useEffect(() => {
137
152
  if (sharedScaleRange) {
138
153
  const {
139
154
  min,
140
155
  max
141
156
  } = {
142
- min: dataset.controls.range[0] * (dataset.controls.valueRange[1] - dataset.controls.valueRange[0]) + dataset.controls.valueRange[0],
143
- max: dataset.controls.range[1] * (dataset.controls.valueRange[1] - dataset.controls.valueRange[0]) + dataset.controls.valueRange[0]
157
+ min: settings.controls.range[0] * (settings.controls.valueRange[1] - settings.controls.valueRange[0]) + settings.controls.valueRange[0],
158
+ max: settings.controls.range[1] * (settings.controls.valueRange[1] - settings.controls.valueRange[0]) + settings.controls.valueRange[0]
144
159
  };
145
160
  setData(d => {
146
161
  return _.map(d, trace => {
@@ -151,40 +166,36 @@ export function Pseudospatial(_ref) {
151
166
  const color = rgbToHex(getColor({
152
167
  value: (v - min) / (max - min)
153
168
  }));
154
- return {
155
- ...trace,
169
+ return _objectSpread(_objectSpread({}, trace), {}, {
156
170
  fillcolor: color,
157
- line: {
158
- ...trace.line,
171
+ line: _objectSpread(_objectSpread({}, trace.line), {}, {
159
172
  color: color
160
- }
161
- };
173
+ })
174
+ });
162
175
  });
163
176
  });
164
177
  setLayout(l => {
165
- return {
166
- ...l,
167
- coloraxis: {
168
- ...l.coloraxis,
178
+ return _objectSpread(_objectSpread({}, l), {}, {
179
+ coloraxis: _objectSpread(_objectSpread({}, l.coloraxis), {}, {
169
180
  cmin: min,
170
181
  cmax: max
171
- }
172
- };
182
+ })
183
+ });
173
184
  });
174
185
  }
175
- }, [dataset.controls.range, dataset.controls.valueMax, dataset.controls.valueMin, dataset.controls.valueRange, getColor, sharedScaleRange]);
176
- const hasSelections = !!plotType && !!dataset.pseudospatial.maskSet;
186
+ }, [settings.controls.range, settings.controls.valueMax, settings.controls.valueMin, settings.controls.valueRange, getColor, sharedScaleRange]);
187
+ const hasSelections = !!plotType && !!settings.pseudospatial.maskSet;
177
188
  const faSlidersPath = faSliders.icon[4];
178
189
  if (!serverError) {
190
+ var _layout$coloraxis5, _layout$coloraxis6;
179
191
  return /*#__PURE__*/React.createElement("div", {
180
192
  className: "cherita-pseudospatial"
181
193
  }, /*#__PURE__*/React.createElement(React.Fragment, null, hasSelections && isPending && /*#__PURE__*/React.createElement(LoadingSpinner, null), hasSelections && /*#__PURE__*/React.createElement(Plot, {
182
194
  data: data,
183
- layout: {
184
- ...layout,
195
+ layout: _objectSpread(_objectSpread({}, layout), {}, {
185
196
  autosize: true,
186
197
  height: height
187
- },
198
+ }),
188
199
  useResizeHandler: true,
189
200
  className: "cherita-pseudospatial-plot",
190
201
  config: {
@@ -203,8 +214,8 @@ export function Pseudospatial(_ref) {
203
214
  }]
204
215
  }
205
216
  }), hasSelections && showLegend && /*#__PURE__*/React.createElement(Legend, {
206
- min: layout?.coloraxis?.cmin,
207
- max: layout?.coloraxis?.cmax,
217
+ min: layout === null || layout === void 0 || (_layout$coloraxis5 = layout.coloraxis) === null || _layout$coloraxis5 === void 0 ? void 0 : _layout$coloraxis5.cmin,
218
+ max: layout === null || layout === void 0 || (_layout$coloraxis6 = layout.coloraxis) === null || _layout$coloraxis6 === void 0 ? void 0 : _layout$coloraxis6.cmax,
208
219
  addText: plotType === PLOT_TYPES.GENE ? " - Mean expression" : plotType === PLOT_TYPES.CATEGORICAL ? " - %" : plotType === PLOT_TYPES.CONTINUOUS ? " - Mean value" : ""
209
220
  })));
210
221
  } else {