@haniffalab/cherita-react 1.4.1-dev.2025-10-22.61540191 → 1.4.1-dev.2025-10-23.3179e534

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 (103) hide show
  1. package/dist/cjs/components/controls/Controls.js +38 -30
  2. package/dist/cjs/components/dotplot/Dotplot.js +40 -33
  3. package/dist/cjs/components/dotplot/DotplotControls.js +103 -83
  4. package/dist/cjs/components/full-page/FullPage.js +92 -69
  5. package/dist/cjs/components/full-page/PlotAlert.js +25 -16
  6. package/dist/cjs/components/full-page/PlotTypeSelector.js +43 -36
  7. package/dist/cjs/components/heatmap/Heatmap.js +40 -33
  8. package/dist/cjs/components/heatmap/HeatmapControls.js +6 -3
  9. package/dist/cjs/components/icons/DotPlotIcon.js +16 -10
  10. package/dist/cjs/components/icons/HeatmapIcon.js +17 -11
  11. package/dist/cjs/components/icons/MatrixPlotIcon.1.js +22 -16
  12. package/dist/cjs/components/icons/MatrixPlotIcon.js +22 -16
  13. package/dist/cjs/components/icons/ScatterplotIcon.1.js +21 -15
  14. package/dist/cjs/components/icons/ScatterplotIcon.js +21 -15
  15. package/dist/cjs/components/icons/ViolinPlotIcon.js +22 -14
  16. package/dist/cjs/components/matrixplot/Matrixplot.js +40 -33
  17. package/dist/cjs/components/matrixplot/MatrixplotControls.js +8 -5
  18. package/dist/cjs/components/obs-list/ObsItem.js +238 -190
  19. package/dist/cjs/components/obs-list/ObsList.js +106 -87
  20. package/dist/cjs/components/obs-list/ObsToolbar.js +2 -3
  21. package/dist/cjs/components/obsm-list/ObsmList.js +47 -32
  22. package/dist/cjs/components/offcanvas/index.js +61 -31
  23. package/dist/cjs/components/pseudospatial/Pseudospatial.js +46 -36
  24. package/dist/cjs/components/pseudospatial/PseudospatialToolbar.js +98 -68
  25. package/dist/cjs/components/scatterplot/Scatterplot.js +87 -65
  26. package/dist/cjs/components/scatterplot/ScatterplotControls.js +35 -27
  27. package/dist/cjs/components/scatterplot/SpatialControls.js +134 -107
  28. package/dist/cjs/components/scatterplot/Toolbox.js +41 -30
  29. package/dist/cjs/components/search-bar/SearchBar.js +157 -110
  30. package/dist/cjs/components/search-bar/SearchInfo.js +73 -47
  31. package/dist/cjs/components/search-bar/SearchResults.js +93 -71
  32. package/dist/cjs/components/toolbar/Toolbar.js +43 -34
  33. package/dist/cjs/components/var-list/VarItem.js +106 -79
  34. package/dist/cjs/components/var-list/VarList.js +67 -53
  35. package/dist/cjs/components/var-list/VarListToolbar.js +56 -51
  36. package/dist/cjs/components/var-list/VarSet.js +115 -97
  37. package/dist/cjs/components/violin/Violin.js +77 -58
  38. package/dist/cjs/components/violin/ViolinControls.js +8 -5
  39. package/dist/cjs/context/DatasetContext.js +20 -13
  40. package/dist/cjs/context/FilterContext.js +9 -7
  41. package/dist/cjs/context/SettingsContext.js +11 -9
  42. package/dist/cjs/context/ZarrDataContext.js +6 -5
  43. package/dist/cjs/utils/Histogram.js +35 -33
  44. package/dist/cjs/utils/ImageViewer.js +9 -6
  45. package/dist/cjs/utils/Legend.js +36 -29
  46. package/dist/cjs/utils/LoadingIndicators.js +14 -12
  47. package/dist/cjs/utils/Skeleton.js +10 -10
  48. package/dist/cjs/utils/StyledTooltip.js +7 -2
  49. package/dist/cjs/utils/VirtualizedList.js +32 -25
  50. package/dist/cjs/utils/errors.js +1 -1
  51. package/dist/css/cherita.css +6 -1
  52. package/dist/css/cherita.css.map +1 -1
  53. package/dist/esm/components/controls/Controls.js +38 -30
  54. package/dist/esm/components/dotplot/Dotplot.js +40 -33
  55. package/dist/esm/components/dotplot/DotplotControls.js +103 -82
  56. package/dist/esm/components/full-page/FullPage.js +92 -69
  57. package/dist/esm/components/full-page/PlotAlert.js +25 -16
  58. package/dist/esm/components/full-page/PlotTypeSelector.js +43 -36
  59. package/dist/esm/components/heatmap/Heatmap.js +40 -33
  60. package/dist/esm/components/heatmap/HeatmapControls.js +6 -2
  61. package/dist/esm/components/icons/DotPlotIcon.js +16 -10
  62. package/dist/esm/components/icons/HeatmapIcon.js +17 -11
  63. package/dist/esm/components/icons/MatrixPlotIcon.1.js +22 -16
  64. package/dist/esm/components/icons/MatrixPlotIcon.js +22 -16
  65. package/dist/esm/components/icons/ScatterplotIcon.1.js +21 -15
  66. package/dist/esm/components/icons/ScatterplotIcon.js +21 -15
  67. package/dist/esm/components/icons/ViolinPlotIcon.js +22 -14
  68. package/dist/esm/components/matrixplot/Matrixplot.js +40 -33
  69. package/dist/esm/components/matrixplot/MatrixplotControls.js +8 -4
  70. package/dist/esm/components/obs-list/ObsItem.js +237 -186
  71. package/dist/esm/components/obs-list/ObsList.js +106 -86
  72. package/dist/esm/components/obs-list/ObsToolbar.js +2 -2
  73. package/dist/esm/components/obsm-list/ObsmList.js +47 -31
  74. package/dist/esm/components/offcanvas/index.js +61 -31
  75. package/dist/esm/components/pseudospatial/Pseudospatial.js +46 -36
  76. package/dist/esm/components/pseudospatial/PseudospatialToolbar.js +98 -68
  77. package/dist/esm/components/scatterplot/Scatterplot.js +87 -64
  78. package/dist/esm/components/scatterplot/ScatterplotControls.js +35 -26
  79. package/dist/esm/components/scatterplot/SpatialControls.js +134 -106
  80. package/dist/esm/components/scatterplot/Toolbox.js +41 -29
  81. package/dist/esm/components/search-bar/SearchBar.js +157 -109
  82. package/dist/esm/components/search-bar/SearchInfo.js +73 -46
  83. package/dist/esm/components/search-bar/SearchResults.js +93 -70
  84. package/dist/esm/components/toolbar/Toolbar.js +43 -33
  85. package/dist/esm/components/var-list/VarItem.js +106 -78
  86. package/dist/esm/components/var-list/VarList.js +67 -52
  87. package/dist/esm/components/var-list/VarListToolbar.js +56 -50
  88. package/dist/esm/components/var-list/VarSet.js +115 -96
  89. package/dist/esm/components/violin/Violin.js +77 -58
  90. package/dist/esm/components/violin/ViolinControls.js +8 -4
  91. package/dist/esm/context/DatasetContext.js +20 -12
  92. package/dist/esm/context/FilterContext.js +9 -6
  93. package/dist/esm/context/SettingsContext.js +11 -8
  94. package/dist/esm/context/ZarrDataContext.js +6 -4
  95. package/dist/esm/utils/Histogram.js +35 -33
  96. package/dist/esm/utils/ImageViewer.js +9 -5
  97. package/dist/esm/utils/Legend.js +36 -28
  98. package/dist/esm/utils/LoadingIndicators.js +14 -11
  99. package/dist/esm/utils/Skeleton.js +10 -9
  100. package/dist/esm/utils/StyledTooltip.js +7 -2
  101. package/dist/esm/utils/VirtualizedList.js +32 -24
  102. package/dist/esm/utils/errors.js +1 -1
  103. package/package.json +3 -3
@@ -5,25 +5,31 @@ import { ButtonGroup, Dropdown, Form } from "react-bootstrap";
5
5
  import { PSEUDOSPATIAL_CATEGORICAL_MODES as MODES, PSEUDOSPATIAL_PLOT_TYPES as PLOT_TYPES } from "../../constants/constants";
6
6
  import { useDataset } from "../../context/DatasetContext";
7
7
  import { useSettings, useSettingsDispatch } from "../../context/SettingsContext";
8
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
8
9
  function CategoricalMode() {
9
10
  const settings = useSettings();
10
11
  const dispatch = useSettingsDispatch();
11
- const modeList = _.map(MODES, (m, key) => /*#__PURE__*/React.createElement(Dropdown.Item, {
12
- key: key,
12
+ const modeList = _.map(MODES, (m, key) => /*#__PURE__*/_jsx(Dropdown.Item, {
13
13
  active: settings.pseudospatial.categoricalMode === m,
14
14
  onClick: () => {
15
15
  dispatch({
16
16
  type: "set.pseudospatial.categoricalMode",
17
17
  categoricalMode: m.value
18
18
  });
19
- }
20
- }, _.capitalize(m.name)));
19
+ },
20
+ children: _.capitalize(m.name)
21
+ }, key));
21
22
  const mode = _.find(MODES, {
22
23
  value: settings.pseudospatial.categoricalMode
23
24
  });
24
- return /*#__PURE__*/React.createElement(Dropdown, null, /*#__PURE__*/React.createElement(Dropdown.Toggle, {
25
- variant: "light"
26
- }, _.capitalize(mode.name)), /*#__PURE__*/React.createElement(Dropdown.Menu, null, modeList));
25
+ return /*#__PURE__*/_jsxs(Dropdown, {
26
+ children: [/*#__PURE__*/_jsx(Dropdown.Toggle, {
27
+ variant: "light",
28
+ children: _.capitalize(mode.name)
29
+ }), /*#__PURE__*/_jsx(Dropdown.Menu, {
30
+ children: modeList
31
+ })]
32
+ });
27
33
  }
28
34
  function MaskSet() {
29
35
  var _settings$pseudospati5, _settings$pseudospati6, _maskSets$settings$ps2, _settings$pseudospati7, _settings$pseudospati8, _maskSets$settings$ps3, _settings$pseudospati9;
@@ -32,16 +38,16 @@ function MaskSet() {
32
38
  const {
33
39
  pseudospatial: maskSets
34
40
  } = settings.data;
35
- const maskSetList = _.map(maskSets, (ms, key) => /*#__PURE__*/React.createElement(Dropdown.Item, {
36
- key: key,
41
+ const maskSetList = _.map(maskSets, (ms, key) => /*#__PURE__*/_jsx(Dropdown.Item, {
37
42
  active: settings.pseudospatial.maskSet === key,
38
43
  onClick: () => {
39
44
  dispatch({
40
45
  type: "set.pseudospatial.maskSet",
41
46
  maskSet: key
42
47
  });
43
- }
44
- }, _.capitalize(key)));
48
+ },
49
+ children: _.capitalize(key)
50
+ }, key));
45
51
  const handleMaskChange = mask => {
46
52
  var _settings$pseudospati, _settings$pseudospati2;
47
53
  let newMasks = settings.pseudospatial.maskValues || (maskSets === null || maskSets === void 0 ? void 0 : maskSets[(_settings$pseudospati = settings.pseudospatial) === null || _settings$pseudospati === void 0 ? void 0 : _settings$pseudospati.maskSet]);
@@ -68,28 +74,44 @@ function MaskSet() {
68
74
  });
69
75
  }
70
76
  };
71
- const masksList = _.map(maskSets === null || maskSets === void 0 ? void 0 : maskSets[(_settings$pseudospati5 = settings.pseudospatial) === null || _settings$pseudospati5 === void 0 ? void 0 : _settings$pseudospati5.maskSet], mask => /*#__PURE__*/React.createElement(Dropdown.ItemText, {
72
- key: mask
73
- }, /*#__PURE__*/React.createElement(Form.Check, {
74
- type: "checkbox",
75
- label: mask,
76
- checked: !settings.pseudospatial.maskValues || settings.pseudospatial.maskValues.includes(mask),
77
- onChange: () => handleMaskChange(mask)
78
- })));
77
+ const masksList = _.map(maskSets === null || maskSets === void 0 ? void 0 : maskSets[(_settings$pseudospati5 = settings.pseudospatial) === null || _settings$pseudospati5 === void 0 ? void 0 : _settings$pseudospati5.maskSet], mask => /*#__PURE__*/_jsx(Dropdown.ItemText, {
78
+ children: /*#__PURE__*/_jsx(Form.Check, {
79
+ type: "checkbox",
80
+ label: mask,
81
+ checked: !settings.pseudospatial.maskValues || settings.pseudospatial.maskValues.includes(mask),
82
+ onChange: () => handleMaskChange(mask)
83
+ })
84
+ }, mask));
79
85
  const nMasks = settings.pseudospatial.maskValues ? (_settings$pseudospati6 = settings.pseudospatial.maskValues) === null || _settings$pseudospati6 === void 0 ? void 0 : _settings$pseudospati6.length : (maskSets === null || maskSets === void 0 || (_maskSets$settings$ps2 = maskSets[(_settings$pseudospati7 = settings.pseudospatial) === null || _settings$pseudospati7 === void 0 ? void 0 : _settings$pseudospati7.maskSet]) === null || _maskSets$settings$ps2 === void 0 ? void 0 : _maskSets$settings$ps2.length) || "No";
80
86
  const toggleAllChecked = !settings.pseudospatial.maskValues || ((_settings$pseudospati8 = settings.pseudospatial.maskValues) === null || _settings$pseudospati8 === void 0 ? void 0 : _settings$pseudospati8.length) === (maskSets === null || maskSets === void 0 || (_maskSets$settings$ps3 = maskSets[(_settings$pseudospati9 = settings.pseudospatial) === null || _settings$pseudospati9 === void 0 ? void 0 : _settings$pseudospati9.maskSet]) === null || _maskSets$settings$ps3 === void 0 ? void 0 : _maskSets$settings$ps3.length);
81
- return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Dropdown, null, /*#__PURE__*/React.createElement(Dropdown.Toggle, {
82
- variant: "light"
83
- }, _.capitalize(settings.pseudospatial.maskSet || "Select a mask set")), /*#__PURE__*/React.createElement(Dropdown.Menu, null, /*#__PURE__*/React.createElement(Dropdown.Header, null, "Mask set"), maskSetList)), /*#__PURE__*/React.createElement(Dropdown, null, /*#__PURE__*/React.createElement(Dropdown.Toggle, {
84
- variant: "light"
85
- }, nMasks, " masks selected"), /*#__PURE__*/React.createElement(Dropdown.Menu, null, /*#__PURE__*/React.createElement(Dropdown.Header, null, "Masks"), /*#__PURE__*/React.createElement(Dropdown.ItemText, {
86
- key: "toggle-all"
87
- }, /*#__PURE__*/React.createElement(Form.Check, {
88
- type: "checkbox",
89
- label: "Toggle all",
90
- checked: toggleAllChecked,
91
- onChange: toggleMasks
92
- })), masksList)));
87
+ return /*#__PURE__*/_jsxs(_Fragment, {
88
+ children: [/*#__PURE__*/_jsxs(Dropdown, {
89
+ children: [/*#__PURE__*/_jsx(Dropdown.Toggle, {
90
+ variant: "light",
91
+ children: _.capitalize(settings.pseudospatial.maskSet || "Select a mask set")
92
+ }), /*#__PURE__*/_jsxs(Dropdown.Menu, {
93
+ children: [/*#__PURE__*/_jsx(Dropdown.Header, {
94
+ children: "Mask set"
95
+ }), maskSetList]
96
+ })]
97
+ }), /*#__PURE__*/_jsxs(Dropdown, {
98
+ children: [/*#__PURE__*/_jsxs(Dropdown.Toggle, {
99
+ variant: "light",
100
+ children: [nMasks, " masks selected"]
101
+ }), /*#__PURE__*/_jsxs(Dropdown.Menu, {
102
+ children: [/*#__PURE__*/_jsx(Dropdown.Header, {
103
+ children: "Masks"
104
+ }), /*#__PURE__*/_jsx(Dropdown.ItemText, {
105
+ children: /*#__PURE__*/_jsx(Form.Check, {
106
+ type: "checkbox",
107
+ label: "Toggle all",
108
+ checked: toggleAllChecked,
109
+ onChange: toggleMasks
110
+ })
111
+ }, "toggle-all"), masksList]
112
+ })]
113
+ })]
114
+ });
93
115
  }
94
116
  function OpacitySlider(_ref) {
95
117
  let {
@@ -97,32 +119,35 @@ function OpacitySlider(_ref) {
97
119
  setOpacity
98
120
  } = _ref;
99
121
  const [sliderValue, setSliderValue] = useState(opacity);
100
- return /*#__PURE__*/React.createElement(Box, {
101
- className: "w-100"
102
- }, /*#__PURE__*/React.createElement(Typography, {
103
- id: "opacity-range",
104
- gutterBottom: true
105
- }, "Reference image opacity"), /*#__PURE__*/React.createElement("div", {
106
- className: "px-4"
107
- }, /*#__PURE__*/React.createElement(Slider, {
108
- "aria-labelledby": "opacity-range",
109
- min: 0,
110
- max: 1,
111
- step: 0.05,
112
- value: sliderValue,
113
- onChange: (_e, value) => setSliderValue(value),
114
- onChangeCommitted: (_e, value) => setOpacity(value),
115
- valueLabelDisplay: "auto",
116
- getAriaValueText: value => "".concat(value * 100, "%"),
117
- valueLabelFormat: value => "".concat((value * 100).toFixed(0), "%"),
118
- marks: [{
119
- value: 0,
120
- label: "0%"
121
- }, {
122
- value: 1,
123
- label: "100%"
124
- }]
125
- })));
122
+ return /*#__PURE__*/_jsxs(Box, {
123
+ className: "w-100",
124
+ children: [/*#__PURE__*/_jsx(Typography, {
125
+ id: "opacity-range",
126
+ gutterBottom: true,
127
+ children: "Reference image opacity"
128
+ }), /*#__PURE__*/_jsx("div", {
129
+ className: "px-4",
130
+ children: /*#__PURE__*/_jsx(Slider, {
131
+ "aria-labelledby": "opacity-range",
132
+ min: 0,
133
+ max: 1,
134
+ step: 0.05,
135
+ value: sliderValue,
136
+ onChange: (_e, value) => setSliderValue(value),
137
+ onChangeCommitted: (_e, value) => setOpacity(value),
138
+ valueLabelDisplay: "auto",
139
+ getAriaValueText: value => "".concat(value * 100, "%"),
140
+ valueLabelFormat: value => "".concat((value * 100).toFixed(0), "%"),
141
+ marks: [{
142
+ value: 0,
143
+ label: "0%"
144
+ }, {
145
+ value: 1,
146
+ label: "100%"
147
+ }]
148
+ })
149
+ })]
150
+ });
126
151
  }
127
152
 
128
153
  // @TODO: add colormap, colorbar slider
@@ -135,15 +160,20 @@ export function PseudospatialToolbar(_ref2) {
135
160
  } = useDataset();
136
161
  const settings = useSettings();
137
162
  const dispatch = useSettingsDispatch();
138
- return /*#__PURE__*/React.createElement("div", {
139
- className: "cherita-pseudospatial-toolbar"
140
- }, /*#__PURE__*/React.createElement(ButtonGroup, null, /*#__PURE__*/React.createElement(MaskSet, null)), /*#__PURE__*/React.createElement(ButtonGroup, null, plotType === PLOT_TYPES.CATEGORICAL && /*#__PURE__*/React.createElement(CategoricalMode, null)), imageUrl && /*#__PURE__*/React.createElement(OpacitySlider, {
141
- opacity: settings.pseudospatial.refImg.opacity,
142
- setOpacity: opacity => {
143
- dispatch({
144
- type: "set.pseudospatial.refImg.opacity",
145
- opacity: opacity
146
- });
147
- }
148
- }));
163
+ return /*#__PURE__*/_jsxs("div", {
164
+ className: "cherita-pseudospatial-toolbar",
165
+ children: [/*#__PURE__*/_jsx(ButtonGroup, {
166
+ children: /*#__PURE__*/_jsx(MaskSet, {})
167
+ }), /*#__PURE__*/_jsx(ButtonGroup, {
168
+ children: plotType === PLOT_TYPES.CATEGORICAL && /*#__PURE__*/_jsx(CategoricalMode, {})
169
+ }), imageUrl && /*#__PURE__*/_jsx(OpacitySlider, {
170
+ opacity: settings.pseudospatial.refImg.opacity,
171
+ setOpacity: opacity => {
172
+ dispatch({
173
+ type: "set.pseudospatial.refImg.opacity",
174
+ opacity: opacity
175
+ });
176
+ }
177
+ })]
178
+ });
149
179
  }
@@ -3,7 +3,7 @@ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t =
3
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
4
  function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
5
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); }
6
- import React, { useCallback, useDeferredValue, useEffect, useMemo, useRef, useState } from "react";
6
+ import { useCallback, useDeferredValue, useEffect, useMemo, useRef, useState } from "react";
7
7
  import { ScatterplotLayer } from "@deck.gl/layers";
8
8
  import { DeckGL } from "@deck.gl/react";
9
9
  import { faTriangleExclamation } from "@fortawesome/free-solid-svg-icons";
@@ -12,8 +12,6 @@ import { ViewMode } from "@nebula.gl/edit-modes";
12
12
  import { EditableGeoJsonLayer } from "@nebula.gl/layers";
13
13
  import _ from "lodash";
14
14
  import { Alert } from "react-bootstrap";
15
- import { SpatialControls } from "./SpatialControls";
16
- import { Toolbox } from "./Toolbox";
17
15
  import { COLOR_ENCODINGS, OBS_TYPES, SELECTED_POLYGON_FILLCOLOR, UNSELECTED_POLYGON_FILLCOLOR } from "../../constants/constants";
18
16
  import { useDataset } from "../../context/DatasetContext";
19
17
  import { useFilteredData } from "../../context/FilterContext";
@@ -26,6 +24,10 @@ import { LoadingLinear, LoadingSpinner } from "../../utils/LoadingIndicators";
26
24
  import { useSelectedObs } from "../../utils/Resolver";
27
25
  import { formatNumerical } from "../../utils/string";
28
26
  import { useLabelObsData } from "../../utils/zarrData";
27
+ import { PlotAlert } from "../full-page/PlotAlert";
28
+ import { SpatialControls } from "./SpatialControls";
29
+ import { Toolbox } from "./Toolbox";
30
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
29
31
  window.deck.log.level = 1;
30
32
  const INITIAL_VIEW_STATE = {
31
33
  longitude: 0,
@@ -41,6 +43,8 @@ export function Scatterplot(_ref) {
41
43
  radius = null,
42
44
  setShowObs,
43
45
  setShowVars,
46
+ plotType,
47
+ setPlotType,
44
48
  isFullscreen = false
45
49
  } = _ref;
46
50
  const {
@@ -67,6 +71,7 @@ export function Scatterplot(_ref) {
67
71
  values: []
68
72
  });
69
73
  const [coordsError, setCoordsError] = useState(null);
74
+ const [hasObsm, setHasObsm] = useState(true);
70
75
  const [dataError, setDataError] = useState(null);
71
76
  const selectedObs = useSelectedObs();
72
77
 
@@ -363,65 +368,83 @@ export function Scatterplot(_ref) {
363
368
  };
364
369
  };
365
370
  const error = settings.selectedObsm && ((_obsmData$serverError = obsmData.serverError) === null || _obsmData$serverError === void 0 ? void 0 : _obsmData$serverError.length) || dataError || settings.labelObs.length && ((_labelObsData$serverE = labelObsData.serverError) === null || _labelObsData$serverE === void 0 ? void 0 : _labelObsData$serverE.length) || coordsError;
366
- return /*#__PURE__*/React.createElement("div", {
367
- className: "cherita-container-scatterplot"
368
- }, /*#__PURE__*/React.createElement("div", {
369
- className: "cherita-scatterplot"
370
- }, obsmData.isPending && /*#__PURE__*/React.createElement(LoadingSpinner, {
371
- disableShrink: true
372
- }), isPending && /*#__PURE__*/React.createElement(LoadingLinear, null), /*#__PURE__*/React.createElement(DeckGL, {
373
- viewState: viewState,
374
- onViewStateChange: e => setViewState(e.viewState),
375
- controller: {
376
- doubleClickZoom: mode === ViewMode
377
- },
378
- layers: layers,
379
- onClick: onLayerClick,
380
- getTooltip: getTooltip,
381
- onAfterRender: () => {
382
- setIsRendering(false);
383
- },
384
- useDevicePixels: false,
385
- getCursor: _ref6 => {
386
- let {
387
- isDragging
388
- } = _ref6;
389
- return mode !== ViewMode ? "crosshair" : isDragging ? "grabbing" : "grab";
390
- },
391
- ref: deckRef
392
- }), /*#__PURE__*/React.createElement(SpatialControls, {
393
- mode: mode,
394
- setMode: setMode,
395
- features: features,
396
- setFeatures: setFeatures,
397
- selectedFeatureIndexes: selectedFeatureIndexes,
398
- resetBounds: () => setViewState(getBounds()),
399
- increaseZoom: () => setViewState(v => _objectSpread(_objectSpread({}, v), {}, {
400
- zoom: v.zoom + 1
401
- })),
402
- decreaseZoom: () => setViewState(v => _objectSpread(_objectSpread({}, v), {}, {
403
- zoom: v.zoom - 1
404
- })),
405
- setShowObs: setShowObs,
406
- setShowVars: setShowVars,
407
- isFullscreen: isFullscreen
408
- }), /*#__PURE__*/React.createElement("div", {
409
- className: "cherita-spatial-footer"
410
- }, /*#__PURE__*/React.createElement("div", {
411
- className: "cherita-toolbox-footer"
412
- }, !!error && !isRendering && /*#__PURE__*/React.createElement(Alert, {
413
- variant: "danger"
414
- }, /*#__PURE__*/React.createElement(Alert.Heading, null, /*#__PURE__*/React.createElement(FontAwesomeIcon, {
415
- icon: faTriangleExclamation
416
- }), "\xA0Error loading data"), /*#__PURE__*/React.createElement("p", {
417
- className: "mb-0"
418
- }, error.message)), /*#__PURE__*/React.createElement(Toolbox, {
419
- mode: settings.colorEncoding === COLOR_ENCODINGS.VAR ? (_settings$selectedVar = settings.selectedVar) === null || _settings$selectedVar === void 0 ? void 0 : _settings$selectedVar.name : settings.colorEncoding === COLOR_ENCODINGS.OBS ? selectedObs === null || selectedObs === void 0 ? void 0 : selectedObs.name : null,
420
- obsLength: parseInt((_data$positions = data.positions) === null || _data$positions === void 0 ? void 0 : _data$positions.length),
421
- slicedLength: parseInt(slicedLength)
422
- })), !error && /*#__PURE__*/React.createElement(Legend, {
423
- isCategorical: isCategorical,
424
- min: min,
425
- max: max
426
- }))));
371
+ if (!hasObsm) {
372
+ return /*#__PURE__*/_jsx(PlotAlert, {
373
+ variant: "info",
374
+ heading: "Scatterplot unavailable for this dataset",
375
+ plotType: plotType,
376
+ setPlotType: setPlotType,
377
+ children: "This dataset does not include any embeddings, so a scatterplot cannot be displayed. Please choose a different plot type to explore the data."
378
+ });
379
+ }
380
+ return /*#__PURE__*/_jsx("div", {
381
+ className: "cherita-container-scatterplot",
382
+ children: /*#__PURE__*/_jsxs("div", {
383
+ className: "cherita-scatterplot",
384
+ children: [obsmData.isPending && /*#__PURE__*/_jsx(LoadingSpinner, {
385
+ disableShrink: true
386
+ }), isPending && /*#__PURE__*/_jsx(LoadingLinear, {}), /*#__PURE__*/_jsx(DeckGL, {
387
+ viewState: viewState,
388
+ onViewStateChange: e => setViewState(e.viewState),
389
+ controller: {
390
+ doubleClickZoom: mode === ViewMode
391
+ },
392
+ layers: layers,
393
+ onClick: onLayerClick,
394
+ getTooltip: getTooltip,
395
+ onAfterRender: () => {
396
+ setIsRendering(false);
397
+ },
398
+ useDevicePixels: false,
399
+ getCursor: _ref6 => {
400
+ let {
401
+ isDragging
402
+ } = _ref6;
403
+ return mode !== ViewMode ? "crosshair" : isDragging ? "grabbing" : "grab";
404
+ },
405
+ ref: deckRef
406
+ }), /*#__PURE__*/_jsx(SpatialControls, {
407
+ mode: mode,
408
+ setMode: setMode,
409
+ features: features,
410
+ setFeatures: setFeatures,
411
+ selectedFeatureIndexes: selectedFeatureIndexes,
412
+ resetBounds: () => setViewState(getBounds()),
413
+ increaseZoom: () => setViewState(v => _objectSpread(_objectSpread({}, v), {}, {
414
+ zoom: v.zoom + 1
415
+ })),
416
+ decreaseZoom: () => setViewState(v => _objectSpread(_objectSpread({}, v), {}, {
417
+ zoom: v.zoom - 1
418
+ })),
419
+ setShowObs: setShowObs,
420
+ setShowVars: setShowVars,
421
+ isFullscreen: isFullscreen
422
+ }), /*#__PURE__*/_jsxs("div", {
423
+ className: "cherita-spatial-footer",
424
+ children: [/*#__PURE__*/_jsxs("div", {
425
+ className: "cherita-toolbox-footer",
426
+ children: [!!error && !isRendering && /*#__PURE__*/_jsxs(Alert, {
427
+ variant: "danger",
428
+ children: [/*#__PURE__*/_jsxs(Alert.Heading, {
429
+ children: [/*#__PURE__*/_jsx(FontAwesomeIcon, {
430
+ icon: faTriangleExclamation
431
+ }), "\xA0Error loading data"]
432
+ }), /*#__PURE__*/_jsx("p", {
433
+ className: "mb-0",
434
+ children: error.message
435
+ })]
436
+ }), /*#__PURE__*/_jsx(Toolbox, {
437
+ mode: settings.colorEncoding === COLOR_ENCODINGS.VAR ? (_settings$selectedVar = settings.selectedVar) === null || _settings$selectedVar === void 0 ? void 0 : _settings$selectedVar.name : settings.colorEncoding === COLOR_ENCODINGS.OBS ? selectedObs === null || selectedObs === void 0 ? void 0 : selectedObs.name : null,
438
+ obsLength: parseInt((_data$positions = data.positions) === null || _data$positions === void 0 ? void 0 : _data$positions.length),
439
+ slicedLength: parseInt(slicedLength),
440
+ setHasObsm: setHasObsm
441
+ })]
442
+ }), !error && /*#__PURE__*/_jsx(Legend, {
443
+ isCategorical: isCategorical,
444
+ min: min,
445
+ max: max
446
+ })]
447
+ })]
448
+ })
449
+ });
427
450
  }
@@ -1,4 +1,4 @@
1
- import React, { useEffect } from "react";
1
+ import { useState, useEffect } from "react";
2
2
  import { Box, Slider, Typography } from "@mui/material";
3
3
  import { Form } from "react-bootstrap";
4
4
  import { COLOR_ENCODINGS, OBS_TYPES } from "../../constants/constants";
@@ -6,10 +6,11 @@ import { useFilteredData } from "../../context/FilterContext";
6
6
  import { useSettings, useSettingsDispatch } from "../../context/SettingsContext";
7
7
  import { useSelectedObs } from "../../utils/Resolver";
8
8
  import { ColorscaleSelect } from "../controls/Controls";
9
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
9
10
  export const ScatterplotControls = () => {
10
11
  const settings = useSettings();
11
12
  const dispatch = useSettingsDispatch();
12
- const [sliderValue, setSliderValue] = React.useState(settings.controls.range || [0, 1]);
13
+ const [sliderValue, setSliderValue] = useState(settings.controls.range || [0, 1]);
13
14
  const {
14
15
  valueMin,
15
16
  valueMax
@@ -39,28 +40,36 @@ export const ScatterplotControls = () => {
39
40
  useEffect(() => {
40
41
  setSliderValue(settings.controls.range);
41
42
  }, [settings.controls.range]);
42
- const rangeSlider = /*#__PURE__*/React.createElement(Box, {
43
- className: "w-100"
44
- }, /*#__PURE__*/React.createElement(Typography, {
45
- id: "colorscale-range",
46
- gutterBottom: true
47
- }, "Colorscale range"), /*#__PURE__*/React.createElement("div", {
48
- className: "px-4"
49
- }, /*#__PURE__*/React.createElement(Slider, {
50
- "aria-labelledby": "colorscale-range",
51
- min: 0,
52
- max: 1,
53
- step: 0.001,
54
- value: sliderValue,
55
- onChange: updateSlider,
56
- onChangeCommitted: updateRange,
57
- valueLabelDisplay: "auto",
58
- getAriaValueText: valueLabelFormat,
59
- valueLabelFormat: valueLabelFormat,
60
- marks: marks,
61
- disabled: isCategorical
62
- })));
63
- return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Form, null, /*#__PURE__*/React.createElement(ColorscaleSelect, null), /*#__PURE__*/React.createElement(Form.Group, {
64
- className: "mb-2"
65
- }, rangeSlider)));
43
+ const rangeSlider = /*#__PURE__*/_jsxs(Box, {
44
+ className: "w-100",
45
+ children: [/*#__PURE__*/_jsx(Typography, {
46
+ id: "colorscale-range",
47
+ gutterBottom: true,
48
+ children: "Colorscale range"
49
+ }), /*#__PURE__*/_jsx("div", {
50
+ className: "px-4",
51
+ children: /*#__PURE__*/_jsx(Slider, {
52
+ "aria-labelledby": "colorscale-range",
53
+ min: 0,
54
+ max: 1,
55
+ step: 0.001,
56
+ value: sliderValue,
57
+ onChange: updateSlider,
58
+ onChangeCommitted: updateRange,
59
+ valueLabelDisplay: "auto",
60
+ getAriaValueText: valueLabelFormat,
61
+ valueLabelFormat: valueLabelFormat,
62
+ marks: marks,
63
+ disabled: isCategorical
64
+ })
65
+ })]
66
+ });
67
+ return /*#__PURE__*/_jsx(_Fragment, {
68
+ children: /*#__PURE__*/_jsxs(Form, {
69
+ children: [/*#__PURE__*/_jsx(ColorscaleSelect, {}), /*#__PURE__*/_jsx(Form.Group, {
70
+ className: "mb-2",
71
+ children: rangeSlider
72
+ })]
73
+ })
74
+ });
66
75
  };