@haniffalab/cherita-react 1.4.1 → 1.4.2

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 (138) hide show
  1. package/README.md +1 -1
  2. package/dist/cjs/components/controls/Controls.js +38 -30
  3. package/dist/cjs/components/dotplot/Dotplot.js +67 -69
  4. package/dist/cjs/components/dotplot/DotplotControls.js +103 -83
  5. package/dist/cjs/components/full-page/FullPage.js +100 -74
  6. package/dist/cjs/components/full-page/PlotAlert.js +45 -0
  7. package/dist/cjs/components/full-page/PlotTypeSelector.js +89 -44
  8. package/dist/cjs/components/heatmap/Heatmap.js +65 -65
  9. package/dist/cjs/components/heatmap/HeatmapControls.js +6 -3
  10. package/dist/cjs/components/icons/DotPlotIcon.js +64 -0
  11. package/dist/cjs/components/icons/HeatmapIcon.js +45 -0
  12. package/dist/cjs/components/icons/MatrixPlotIcon.1.js +57 -0
  13. package/dist/cjs/components/icons/MatrixPlotIcon.js +59 -0
  14. package/dist/cjs/components/icons/ScatterplotIcon.1.js +164 -0
  15. package/dist/cjs/components/icons/ScatterplotIcon.js +144 -0
  16. package/dist/cjs/components/icons/ViolinPlotIcon.js +42 -0
  17. package/dist/cjs/components/matrixplot/Matrixplot.js +65 -66
  18. package/dist/cjs/components/matrixplot/MatrixplotControls.js +8 -5
  19. package/dist/cjs/components/obs-list/ObsItem.js +258 -210
  20. package/dist/cjs/components/obs-list/ObsList.js +161 -133
  21. package/dist/cjs/components/obs-list/ObsToolbar.js +2 -3
  22. package/dist/cjs/components/obsm-list/ObsmList.js +53 -38
  23. package/dist/cjs/components/offcanvas/index.js +61 -31
  24. package/dist/cjs/components/pseudospatial/Pseudospatial.js +132 -76
  25. package/dist/cjs/components/pseudospatial/PseudospatialToolbar.js +122 -74
  26. package/dist/cjs/components/scatterplot/Scatterplot.js +127 -99
  27. package/dist/cjs/components/scatterplot/ScatterplotControls.js +45 -31
  28. package/dist/cjs/components/scatterplot/SpatialControls.js +140 -113
  29. package/dist/cjs/components/scatterplot/Toolbox.js +41 -30
  30. package/dist/cjs/components/search-bar/SearchBar.js +168 -121
  31. package/dist/cjs/components/search-bar/SearchInfo.js +76 -50
  32. package/dist/cjs/components/search-bar/SearchResults.js +93 -71
  33. package/dist/cjs/components/toolbar/Toolbar.js +46 -37
  34. package/dist/cjs/components/var-list/VarItem.js +115 -88
  35. package/dist/cjs/components/var-list/VarList.js +85 -69
  36. package/dist/cjs/components/var-list/VarListToolbar.js +59 -54
  37. package/dist/cjs/components/var-list/VarSet.js +126 -108
  38. package/dist/cjs/components/violin/Violin.js +109 -107
  39. package/dist/cjs/components/violin/ViolinControls.js +8 -5
  40. package/dist/cjs/constants/colorscales.js +19 -19
  41. package/dist/cjs/constants/constants.js +47 -47
  42. package/dist/cjs/context/DatasetContext.js +24 -16
  43. package/dist/cjs/context/FilterContext.js +11 -9
  44. package/dist/cjs/context/SettingsContext.js +255 -89
  45. package/dist/cjs/context/ZarrDataContext.js +6 -5
  46. package/dist/cjs/helpers/color-helper.js +2 -2
  47. package/dist/cjs/helpers/zarr-helper.js +3 -3
  48. package/dist/cjs/utils/Filter.js +16 -11
  49. package/dist/cjs/utils/Histogram.js +35 -33
  50. package/dist/cjs/utils/ImageViewer.js +11 -8
  51. package/dist/cjs/utils/Legend.js +37 -30
  52. package/dist/cjs/utils/LoadingIndicators.js +15 -13
  53. package/dist/cjs/utils/Resolver.js +213 -0
  54. package/dist/cjs/utils/Skeleton.js +10 -10
  55. package/dist/cjs/utils/StyledTooltip.js +44 -0
  56. package/dist/cjs/utils/VirtualizedList.js +34 -27
  57. package/dist/cjs/utils/errors.js +15 -15
  58. package/dist/cjs/utils/requests.js +21 -9
  59. package/dist/cjs/utils/search.js +4 -4
  60. package/dist/cjs/utils/string.js +6 -6
  61. package/dist/cjs/utils/zarrData.js +20 -21
  62. package/dist/css/cherita.css +64 -42
  63. package/dist/css/cherita.css.map +1 -1
  64. package/dist/esm/components/controls/Controls.js +43 -35
  65. package/dist/esm/components/dotplot/Dotplot.js +77 -78
  66. package/dist/esm/components/dotplot/DotplotControls.js +106 -85
  67. package/dist/esm/components/full-page/FullPage.js +120 -93
  68. package/dist/esm/components/full-page/PlotAlert.js +39 -0
  69. package/dist/esm/components/full-page/PlotTypeSelector.js +90 -45
  70. package/dist/esm/components/heatmap/Heatmap.js +75 -74
  71. package/dist/esm/components/heatmap/HeatmapControls.js +8 -4
  72. package/dist/esm/components/icons/DotPlotIcon.js +58 -0
  73. package/dist/esm/components/icons/HeatmapIcon.js +39 -0
  74. package/dist/esm/components/icons/MatrixPlotIcon.1.js +51 -0
  75. package/dist/esm/components/icons/MatrixPlotIcon.js +53 -0
  76. package/dist/esm/components/icons/ScatterplotIcon.1.js +158 -0
  77. package/dist/esm/components/icons/ScatterplotIcon.js +138 -0
  78. package/dist/esm/components/icons/ViolinPlotIcon.js +36 -0
  79. package/dist/esm/components/matrixplot/Matrixplot.js +75 -75
  80. package/dist/esm/components/matrixplot/MatrixplotControls.js +10 -6
  81. package/dist/esm/components/obs-list/ObsItem.js +273 -222
  82. package/dist/esm/components/obs-list/ObsList.js +176 -147
  83. package/dist/esm/components/obs-list/ObsToolbar.js +3 -3
  84. package/dist/esm/components/obsm-list/ObsmList.js +60 -44
  85. package/dist/esm/components/offcanvas/index.js +67 -37
  86. package/dist/esm/components/pseudospatial/Pseudospatial.js +145 -88
  87. package/dist/esm/components/pseudospatial/PseudospatialToolbar.js +127 -78
  88. package/dist/esm/components/scatterplot/Scatterplot.js +148 -119
  89. package/dist/esm/components/scatterplot/ScatterplotControls.js +50 -35
  90. package/dist/esm/components/scatterplot/SpatialControls.js +153 -125
  91. package/dist/esm/components/scatterplot/Toolbox.js +44 -32
  92. package/dist/esm/components/search-bar/SearchBar.js +180 -132
  93. package/dist/esm/components/search-bar/SearchInfo.js +86 -59
  94. package/dist/esm/components/search-bar/SearchResults.js +100 -77
  95. package/dist/esm/components/toolbar/Toolbar.js +49 -39
  96. package/dist/esm/components/var-list/VarItem.js +126 -98
  97. package/dist/esm/components/var-list/VarList.js +99 -82
  98. package/dist/esm/components/var-list/VarListToolbar.js +64 -58
  99. package/dist/esm/components/var-list/VarSet.js +134 -115
  100. package/dist/esm/components/violin/Violin.js +121 -118
  101. package/dist/esm/components/violin/ViolinControls.js +10 -6
  102. package/dist/esm/constants/colorscales.js +19 -19
  103. package/dist/esm/constants/constants.js +47 -47
  104. package/dist/esm/context/DatasetContext.js +31 -22
  105. package/dist/esm/context/FilterContext.js +11 -8
  106. package/dist/esm/context/SettingsContext.js +257 -90
  107. package/dist/esm/context/ZarrDataContext.js +8 -6
  108. package/dist/esm/helpers/color-helper.js +5 -5
  109. package/dist/esm/helpers/map-helper.js +2 -2
  110. package/dist/esm/helpers/zarr-helper.js +6 -6
  111. package/dist/esm/index.js +22 -22
  112. package/dist/esm/utils/Filter.js +22 -17
  113. package/dist/esm/utils/Histogram.js +39 -37
  114. package/dist/esm/utils/ImageViewer.js +12 -8
  115. package/dist/esm/utils/Legend.js +44 -36
  116. package/dist/esm/utils/LoadingIndicators.js +16 -13
  117. package/dist/esm/utils/Resolver.js +201 -0
  118. package/dist/esm/utils/Skeleton.js +11 -10
  119. package/dist/esm/utils/StyledTooltip.js +38 -0
  120. package/dist/esm/utils/VirtualizedList.js +35 -27
  121. package/dist/esm/utils/errors.js +15 -15
  122. package/dist/esm/utils/requests.js +24 -12
  123. package/dist/esm/utils/search.js +7 -7
  124. package/dist/esm/utils/string.js +7 -7
  125. package/dist/esm/utils/zarrData.js +27 -28
  126. package/package.json +18 -7
  127. package/scss/cherita-bootstrap.scss +2 -2
  128. package/scss/cherita.scss +43 -17
  129. package/scss/components/accordions.scss +4 -1
  130. package/scss/components/layouts.scss +15 -33
  131. package/scss/components/lists.scss +8 -4
  132. package/scss/components/plotly.scss +38 -26
  133. package/scss/components/plots.scss +14 -1
  134. package/dist/assets/images/plots/dotplot.svg +0 -152
  135. package/dist/assets/images/plots/heatmap.svg +0 -193
  136. package/dist/assets/images/plots/matrixplot.svg +0 -275
  137. package/dist/assets/images/plots/scatterplot.svg +0 -198
  138. package/dist/assets/images/plots/violin.svg +0 -50
@@ -3,28 +3,31 @@ 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";
7
- import { ScatterplotLayer } from "@deck.gl/layers";
8
- import { DeckGL } from "@deck.gl/react";
9
- import { faTriangleExclamation } from "@fortawesome/free-solid-svg-icons";
10
- import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
11
- import { ViewMode } from "@nebula.gl/edit-modes";
12
- import { EditableGeoJsonLayer } from "@nebula.gl/layers";
13
- import _ from "lodash";
14
- import { Alert } from "react-bootstrap";
15
- import { SpatialControls } from "./SpatialControls";
16
- import { Toolbox } from "./Toolbox";
17
- import { COLOR_ENCODINGS, OBS_TYPES, SELECTED_POLYGON_FILLCOLOR, UNSELECTED_POLYGON_FILLCOLOR } from "../../constants/constants";
18
- import { useDataset } from "../../context/DatasetContext";
19
- import { useFilteredData } from "../../context/FilterContext";
20
- import { useSettings, useSettingsDispatch } from "../../context/SettingsContext";
21
- import { useZarrData } from "../../context/ZarrDataContext";
22
- import { rgbToHex, useColor } from "../../helpers/color-helper";
23
- import { MapHelper } from "../../helpers/map-helper";
24
- import { Legend } from "../../utils/Legend";
25
- import { LoadingLinear, LoadingSpinner } from "../../utils/LoadingIndicators";
26
- import { formatNumerical } from "../../utils/string";
27
- import { useLabelObsData } from "../../utils/zarrData";
6
+ import { useCallback, useDeferredValue, useEffect, useMemo, useRef, useState } from 'react';
7
+ import { ScatterplotLayer } from '@deck.gl/layers';
8
+ import { DeckGL } from '@deck.gl/react';
9
+ import { faTriangleExclamation } from '@fortawesome/free-solid-svg-icons';
10
+ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
11
+ import { ViewMode } from '@nebula.gl/edit-modes';
12
+ import { EditableGeoJsonLayer } from '@nebula.gl/layers';
13
+ import _ from 'lodash';
14
+ import { Alert } from 'react-bootstrap';
15
+ import { SpatialControls } from './SpatialControls';
16
+ import { Toolbox } from './Toolbox';
17
+ import { COLOR_ENCODINGS, OBS_TYPES, SELECTED_POLYGON_FILLCOLOR, UNSELECTED_POLYGON_FILLCOLOR } from '../../constants/constants';
18
+ import { useDataset } from '../../context/DatasetContext';
19
+ import { useFilteredData } from '../../context/FilterContext';
20
+ import { useSettings, useSettingsDispatch } from '../../context/SettingsContext';
21
+ import { useZarrData } from '../../context/ZarrDataContext';
22
+ import { rgbToHex, useColor } from '../../helpers/color-helper';
23
+ import { MapHelper } from '../../helpers/map-helper';
24
+ import { Legend } from '../../utils/Legend';
25
+ import { LoadingLinear, LoadingSpinner } from '../../utils/LoadingIndicators';
26
+ import { useSelectedObs } from '../../utils/Resolver';
27
+ import { formatNumerical } from '../../utils/string';
28
+ import { useLabelObsData } from '../../utils/zarrData';
29
+ import { PlotAlert } from '../full-page/PlotAlert';
30
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
28
31
  window.deck.log.level = 1;
29
32
  const INITIAL_VIEW_STATE = {
30
33
  longitude: 0,
@@ -35,11 +38,13 @@ const INITIAL_VIEW_STATE = {
35
38
  bearing: 0
36
39
  };
37
40
  export function Scatterplot(_ref) {
38
- var _settings$selectedObs2, _settings$selectedObs5, _settings$selectedObs8, _features$features2, _obsmData$serverError, _xData$serverError, _obsData$serverError, _labelObsData$serverE, _settings$selectedVar, _settings$selectedObs9, _data$positions;
41
+ var _features$features2, _obsmData$serverError, _labelObsData$serverE, _settings$selectedVar, _data$positions;
39
42
  let {
40
43
  radius = null,
41
44
  setShowObs,
42
45
  setShowVars,
46
+ plotType,
47
+ setPlotType,
43
48
  isFullscreen = false
44
49
  } = _ref;
45
50
  const {
@@ -66,11 +71,14 @@ export function Scatterplot(_ref) {
66
71
  values: []
67
72
  });
68
73
  const [coordsError, setCoordsError] = useState(null);
74
+ const [hasObsm, setHasObsm] = useState(true);
75
+ const [dataError, setDataError] = useState(null);
76
+ const selectedObs = useSelectedObs();
69
77
 
70
78
  // EditableGeoJsonLayer
71
79
  const [mode, setMode] = useState(() => ViewMode);
72
80
  const [features, setFeatures] = useState({
73
- type: "FeatureCollection",
81
+ type: 'FeatureCollection',
74
82
  features: settings.polygons[settings.selectedObsm] || []
75
83
  });
76
84
  const [selectedFeatureIndexes, setSelectedFeatureIndexes] = useState([]);
@@ -99,13 +107,25 @@ export function Scatterplot(_ref) {
99
107
  setData(d => {
100
108
  let values = d.values;
101
109
  if (settings.colorEncoding === COLOR_ENCODINGS.VAR) {
102
- values = !xData.serverError ? xData.data : values;
110
+ if (!xData.serverError) {
111
+ values = xData.data;
112
+ setDataError(null);
113
+ } else {
114
+ values = [];
115
+ setDataError(xData.serverError);
116
+ }
103
117
  } else if (settings.colorEncoding === COLOR_ENCODINGS.OBS) {
104
- values = !obsData.serverError ? obsData.data : values;
118
+ if (!obsData.serverError) {
119
+ values = obsData.data;
120
+ setDataError(null);
121
+ } else {
122
+ values = [];
123
+ setDataError(obsData.serverError);
124
+ }
105
125
  }
106
126
  if (!obsmData.serverError && obsmData.data) {
107
127
  if (obsmData.data[0].length !== 2) {
108
- setCoordsError("Invalid coordinates. Expected 2D coordinates");
128
+ setCoordsError('Invalid coordinates. Expected 2D coordinates');
109
129
  return {
110
130
  positions: [],
111
131
  values: []
@@ -174,8 +194,7 @@ export function Scatterplot(_ref) {
174
194
  getOriginalIndex,
175
195
  sortedIndexMap
176
196
  } = useMemo(() => {
177
- var _settings$selectedObs;
178
- if ((settings.colorEncoding === COLOR_ENCODINGS.VAR || settings.colorEncoding === COLOR_ENCODINGS.OBS && ((_settings$selectedObs = settings.selectedObs) === null || _settings$selectedObs === void 0 ? void 0 : _settings$selectedObs.type) === OBS_TYPES.CONTINUOUS) && data.positions && data.values && data.positions.length === data.values.length) {
197
+ if ((settings.colorEncoding === COLOR_ENCODINGS.VAR || settings.colorEncoding === COLOR_ENCODINGS.OBS && (selectedObs === null || selectedObs === void 0 ? void 0 : selectedObs.type) === OBS_TYPES.CONTINUOUS) && data.positions && data.values && data.positions.length === data.values.length) {
179
198
  const sortedIndices = _.map(data.values, (_v, i) => i).sort((a, b) => data.values[a] - data.values[b]);
180
199
  const sortedIndexMap = new Map(_.map(sortedIndices, (originalIndex, sortedIndex) => [originalIndex, sortedIndex]));
181
200
  return {
@@ -192,24 +211,17 @@ export function Scatterplot(_ref) {
192
211
  // return original index
193
212
  sortedIndexMap: identitySortedIndexMap // return original index
194
213
  };
195
- }, [data, identityGetOriginalIndex, identitySortedIndexMap, settings.colorEncoding, (_settings$selectedObs2 = settings.selectedObs) === null || _settings$selectedObs2 === void 0 ? void 0 : _settings$selectedObs2.type]);
214
+ }, [data, identityGetOriginalIndex, identitySortedIndexMap, selectedObs === null || selectedObs === void 0 ? void 0 : selectedObs.type, settings.colorEncoding]);
196
215
  const sortedObsIndices = useMemo(() => {
197
216
  return obsIndices ? new Set(Array.from(obsIndices, i => sortedIndexMap.get(i))) : obsIndices;
198
217
  }, [obsIndices, sortedIndexMap]);
199
218
  const isCategorical = useMemo(() => {
200
219
  if (settings.colorEncoding === COLOR_ENCODINGS.OBS) {
201
- var _settings$selectedObs3, _settings$selectedObs4;
202
- return ((_settings$selectedObs3 = settings.selectedObs) === null || _settings$selectedObs3 === void 0 ? void 0 : _settings$selectedObs3.type) === OBS_TYPES.CATEGORICAL || ((_settings$selectedObs4 = settings.selectedObs) === null || _settings$selectedObs4 === void 0 ? void 0 : _settings$selectedObs4.type) === OBS_TYPES.BOOLEAN;
220
+ return (selectedObs === null || selectedObs === void 0 ? void 0 : selectedObs.type) === OBS_TYPES.CATEGORICAL || (selectedObs === null || selectedObs === void 0 ? void 0 : selectedObs.type) === OBS_TYPES.BOOLEAN;
203
221
  } else {
204
222
  return false;
205
223
  }
206
- }, [settings.colorEncoding, (_settings$selectedObs5 = settings.selectedObs) === null || _settings$selectedObs5 === void 0 ? void 0 : _settings$selectedObs5.type]);
207
- useEffect(() => {
208
- dispatch({
209
- type: "set.controls.valueRange",
210
- valueRange: [valueMin, valueMax]
211
- });
212
- }, [dispatch, valueMax, valueMin]);
224
+ }, [settings.colorEncoding, selectedObs === null || selectedObs === void 0 ? void 0 : selectedObs.type]);
213
225
  const {
214
226
  min,
215
227
  max
@@ -218,7 +230,6 @@ export function Scatterplot(_ref) {
218
230
  max: settings.controls.range[1] * (valueMax - valueMin) + valueMin
219
231
  };
220
232
  const getFillColor = useCallback((_d, _ref2) => {
221
- var _settings$selectedObs6, _settings$selectedObs7;
222
233
  let {
223
234
  index
224
235
  } = _ref2;
@@ -227,10 +238,10 @@ export function Scatterplot(_ref) {
227
238
  value: (sortedData.values[index] - min) / (max - min),
228
239
  categorical: isCategorical,
229
240
  grayOut: grayOut
230
- }, useUnsColors && settings.colorEncoding === COLOR_ENCODINGS.OBS && (_settings$selectedObs6 = settings.selectedObs) !== null && _settings$selectedObs6 !== void 0 && _settings$selectedObs6.colors ? {
231
- colorscale: (_settings$selectedObs7 = settings.selectedObs) === null || _settings$selectedObs7 === void 0 ? void 0 : _settings$selectedObs7.colors
241
+ }, useUnsColors && settings.colorEncoding === COLOR_ENCODINGS.OBS && selectedObs !== null && selectedObs !== void 0 && selectedObs.colors ? {
242
+ colorscale: selectedObs === null || selectedObs === void 0 ? void 0 : selectedObs.colors
232
243
  } : {})) || [0, 0, 0, 100];
233
- }, [isPending, sortedObsIndices, getColor, sortedData.values, min, max, isCategorical, useUnsColors, settings.colorEncoding, (_settings$selectedObs8 = settings.selectedObs) === null || _settings$selectedObs8 === void 0 ? void 0 : _settings$selectedObs8.colors]);
244
+ }, [isPending, sortedObsIndices, getColor, sortedData.values, min, max, isCategorical, useUnsColors, settings.colorEncoding, selectedObs === null || selectedObs === void 0 ? void 0 : selectedObs.colors]);
234
245
 
235
246
  // @TODO: add support for pseudospatial hover to reflect in radius
236
247
  const getRadius = useCallback((_d, _ref3) => {
@@ -242,7 +253,7 @@ export function Scatterplot(_ref) {
242
253
  }, [sortedObsIndices]);
243
254
  const memoizedLayers = useMemo(() => {
244
255
  return [new ScatterplotLayer({
245
- id: "cherita-layer-scatterplot",
256
+ id: 'cherita-layer-scatterplot',
246
257
  pickable: true,
247
258
  data: sortedData.positions,
248
259
  radiusScale: radiusScale,
@@ -255,7 +266,7 @@ export function Scatterplot(_ref) {
255
266
  getRadius: getRadius
256
267
  }
257
268
  }), new EditableGeoJsonLayer({
258
- id: "cherita-layer-draw",
269
+ id: 'cherita-layer-draw',
259
270
  data: features,
260
271
  mode: mode,
261
272
  selectedFeatureIndexes,
@@ -267,7 +278,7 @@ export function Scatterplot(_ref) {
267
278
  } = _ref4;
268
279
  setFeatures(updatedData);
269
280
  let updatedSelectedFeatureIndexes = selectedFeatureIndexes;
270
- if (editType === "addFeature") {
281
+ if (editType === 'addFeature') {
271
282
  const {
272
283
  featureIndexes
273
284
  } = editContext;
@@ -295,13 +306,13 @@ export function Scatterplot(_ref) {
295
306
  var _features$features;
296
307
  if (!(features !== null && features !== void 0 && (_features$features = features.features) !== null && _features$features !== void 0 && _features$features.length)) {
297
308
  dispatch({
298
- type: "disable.slice.polygons"
309
+ type: 'disable.slice.polygons'
299
310
  });
300
311
  }
301
312
  }, [dispatch, features === null || features === void 0 || (_features$features2 = features.features) === null || _features$features2 === void 0 ? void 0 : _features$features2.length]);
302
313
  useEffect(() => {
303
314
  dispatch({
304
- type: "set.polygons",
315
+ type: 'set.polygons',
305
316
  obsm: settings.selectedObsm,
306
317
  polygons: (features === null || features === void 0 ? void 0 : features.features) || []
307
318
  });
@@ -311,7 +322,7 @@ export function Scatterplot(_ref) {
311
322
  // don't change selection while editing
312
323
  return;
313
324
  }
314
- setSelectedFeatureIndexes(f => info.object ? info.layer.id === "cherita-layer-draw" ? [info.index] : f : []);
325
+ setSelectedFeatureIndexes(f => info.object ? info.layer.id === 'cherita-layer-draw' ? [info.index] : f : []);
315
326
  }
316
327
  const getLabel = function (o, v) {
317
328
  let isVar = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
@@ -326,13 +337,11 @@ export function Scatterplot(_ref) {
326
337
  object,
327
338
  index
328
339
  } = _ref5;
329
- if (!object || (object === null || object === void 0 ? void 0 : object.type) === "Feature") return;
340
+ if (!object || (object === null || object === void 0 ? void 0 : object.type) === 'Feature') return;
330
341
  const text = [];
331
- if (settings.colorEncoding === COLOR_ENCODINGS.OBS && settings.selectedObs && !_.some(settings.labelObs, {
332
- name: settings.selectedObs.name
333
- })) {
342
+ if (settings.colorEncoding === COLOR_ENCODINGS.OBS && selectedObs && !_.includes(settings.labelObs, selectedObs.name)) {
334
343
  var _data$values;
335
- text.push(getLabel(settings.selectedObs, (_data$values = data.values) === null || _data$values === void 0 ? void 0 : _data$values[getOriginalIndex(index)]));
344
+ text.push(getLabel(selectedObs, (_data$values = data.values) === null || _data$values === void 0 ? void 0 : _data$values[getOriginalIndex(index)]));
336
345
  }
337
346
  if (settings.colorEncoding === COLOR_ENCODINGS.VAR && settings.selectedVar) {
338
347
  var _data$values2;
@@ -340,82 +349,102 @@ export function Scatterplot(_ref) {
340
349
  }
341
350
  if (settings.labelObs.length) {
342
351
  text.push(..._.map(labelObsData.data, (v, k) => {
343
- const labelObs = _.find(settings.labelObs, o => o.name === k);
352
+ const labelObs = settings.data.obs[k];
344
353
  return getLabel(labelObs, v[getOriginalIndex(index)]);
345
354
  }));
346
355
  }
347
356
  if (!text.length) return;
348
357
  const grayOut = sortedObsIndices && !sortedObsIndices.has(index);
349
358
  return {
350
- text: text.length ? _.compact(text).join("\n") : null,
351
- className: grayOut ? "tooltip-grayout" : "deck-tooltip",
359
+ text: text.length ? _.compact(text).join('\n') : null,
360
+ className: grayOut ? 'tooltip-grayout' : 'deck-tooltip',
352
361
  style: !grayOut ? {
353
- "border-left": "3px solid ".concat(rgbToHex(getFillColor(null, {
362
+ 'border-left': "3px solid ".concat(rgbToHex(getFillColor(null, {
354
363
  index
355
364
  })))
356
365
  } : {
357
- "border-left": "none"
366
+ 'border-left': 'none'
358
367
  }
359
368
  };
360
369
  };
361
- const error = settings.selectedObsm && ((_obsmData$serverError = obsmData.serverError) === null || _obsmData$serverError === void 0 ? void 0 : _obsmData$serverError.length) || settings.colorEncoding === COLOR_ENCODINGS.VAR && ((_xData$serverError = xData.serverError) === null || _xData$serverError === void 0 ? void 0 : _xData$serverError.length) || settings.colorEncoding === COLOR_ENCODINGS.OBS && ((_obsData$serverError = obsData.serverError) === null || _obsData$serverError === void 0 ? void 0 : _obsData$serverError.length) || settings.labelObs.length && ((_labelObsData$serverE = labelObsData.serverError) === null || _labelObsData$serverE === void 0 ? void 0 : _labelObsData$serverE.length) || coordsError;
362
- return /*#__PURE__*/React.createElement("div", {
363
- className: "cherita-container-scatterplot"
364
- }, /*#__PURE__*/React.createElement("div", {
365
- className: "cherita-scatterplot"
366
- }, obsmData.isPending && /*#__PURE__*/React.createElement(LoadingSpinner, {
367
- disableShrink: true
368
- }), isPending && /*#__PURE__*/React.createElement(LoadingLinear, null), /*#__PURE__*/React.createElement(DeckGL, {
369
- viewState: viewState,
370
- onViewStateChange: e => setViewState(e.viewState),
371
- controller: {
372
- doubleClickZoom: mode === ViewMode
373
- },
374
- layers: layers,
375
- onClick: onLayerClick,
376
- getTooltip: getTooltip,
377
- onAfterRender: () => {
378
- setIsRendering(false);
379
- },
380
- useDevicePixels: false,
381
- getCursor: _ref6 => {
382
- let {
383
- isDragging
384
- } = _ref6;
385
- return mode !== ViewMode ? "crosshair" : isDragging ? "grabbing" : "grab";
386
- },
387
- ref: deckRef
388
- }), /*#__PURE__*/React.createElement(SpatialControls, {
389
- mode: mode,
390
- setMode: setMode,
391
- features: features,
392
- setFeatures: setFeatures,
393
- selectedFeatureIndexes: selectedFeatureIndexes,
394
- resetBounds: () => setViewState(getBounds()),
395
- increaseZoom: () => setViewState(v => _objectSpread(_objectSpread({}, v), {}, {
396
- zoom: v.zoom + 1
397
- })),
398
- decreaseZoom: () => setViewState(v => _objectSpread(_objectSpread({}, v), {}, {
399
- zoom: v.zoom - 1
400
- })),
401
- setShowObs: setShowObs,
402
- setShowVars: setShowVars,
403
- isFullscreen: isFullscreen
404
- }), /*#__PURE__*/React.createElement("div", {
405
- className: "cherita-spatial-footer"
406
- }, /*#__PURE__*/React.createElement("div", {
407
- className: "cherita-toolbox-footer"
408
- }, !!error && !isRendering && /*#__PURE__*/React.createElement(Alert, {
409
- variant: "danger"
410
- }, /*#__PURE__*/React.createElement(FontAwesomeIcon, {
411
- icon: faTriangleExclamation
412
- }), "\xA0Error loading data"), /*#__PURE__*/React.createElement(Toolbox, {
413
- 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 ? (_settings$selectedObs9 = settings.selectedObs) === null || _settings$selectedObs9 === void 0 ? void 0 : _settings$selectedObs9.name : null,
414
- obsLength: parseInt((_data$positions = data.positions) === null || _data$positions === void 0 ? void 0 : _data$positions.length),
415
- slicedLength: parseInt(slicedLength)
416
- })), /*#__PURE__*/React.createElement(Legend, {
417
- isCategorical: isCategorical,
418
- min: min,
419
- max: max
420
- }))));
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;
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
+ });
421
450
  }
@@ -1,17 +1,24 @@
1
- import React, { useEffect } from "react";
2
- import { Box, Slider, Typography } from "@mui/material";
3
- import { Form } from "react-bootstrap";
4
- import { COLOR_ENCODINGS, OBS_TYPES } from "../../constants/constants";
5
- import { useSettings, useSettingsDispatch } from "../../context/SettingsContext";
6
- import { ColorscaleSelect } from "../controls/Controls";
1
+ import { useState, useEffect } from 'react';
2
+ import { Box, Slider, Typography } from '@mui/material';
3
+ import { Form } from 'react-bootstrap';
4
+ import { COLOR_ENCODINGS, OBS_TYPES } from '../../constants/constants';
5
+ import { useFilteredData } from '../../context/FilterContext';
6
+ import { useSettings, useSettingsDispatch } from '../../context/SettingsContext';
7
+ import { useSelectedObs } from '../../utils/Resolver';
8
+ import { ColorscaleSelect } from '../controls/Controls';
9
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
7
10
  export const ScatterplotControls = () => {
8
- var _settings$selectedObs;
9
11
  const settings = useSettings();
10
12
  const dispatch = useSettingsDispatch();
11
- const [sliderValue, setSliderValue] = React.useState(settings.controls.range || [0, 1]);
12
- const isCategorical = settings.colorEncoding === COLOR_ENCODINGS.OBS ? ((_settings$selectedObs = settings.selectedObs) === null || _settings$selectedObs === void 0 ? void 0 : _settings$selectedObs.type) === OBS_TYPES.CATEGORICAL : false;
13
+ const [sliderValue, setSliderValue] = useState(settings.controls.range || [0, 1]);
14
+ const {
15
+ valueMin,
16
+ valueMax
17
+ } = useFilteredData();
18
+ const selectedObs = useSelectedObs();
19
+ const isCategorical = settings.colorEncoding === COLOR_ENCODINGS.OBS ? (selectedObs === null || selectedObs === void 0 ? void 0 : selectedObs.type) === OBS_TYPES.CATEGORICAL : false;
13
20
  const valueLabelFormat = value => {
14
- return (value * (settings.controls.valueRange[1] - settings.controls.valueRange[0]) + settings.controls.valueRange[0]).toFixed(2);
21
+ return (value * (valueMax - valueMin) + valueMin).toFixed(2);
15
22
  };
16
23
  const marks = [{
17
24
  value: 0,
@@ -26,35 +33,43 @@ export const ScatterplotControls = () => {
26
33
  const updateRange = (_e, value) => {
27
34
  setSliderValue(value);
28
35
  dispatch({
29
- type: "set.controls.range",
36
+ type: 'set.controls.range',
30
37
  range: sliderValue
31
38
  });
32
39
  };
33
40
  useEffect(() => {
34
41
  setSliderValue(settings.controls.range);
35
42
  }, [settings.controls.range]);
36
- const rangeSlider = /*#__PURE__*/React.createElement(Box, {
37
- className: "w-100"
38
- }, /*#__PURE__*/React.createElement(Typography, {
39
- id: "colorscale-range",
40
- gutterBottom: true
41
- }, "Colorscale range"), /*#__PURE__*/React.createElement("div", {
42
- className: "px-4"
43
- }, /*#__PURE__*/React.createElement(Slider, {
44
- "aria-labelledby": "colorscale-range",
45
- min: 0,
46
- max: 1,
47
- step: 0.001,
48
- value: sliderValue,
49
- onChange: updateSlider,
50
- onChangeCommitted: updateRange,
51
- valueLabelDisplay: "auto",
52
- getAriaValueText: valueLabelFormat,
53
- valueLabelFormat: valueLabelFormat,
54
- marks: marks,
55
- disabled: isCategorical
56
- })));
57
- return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Form, null, /*#__PURE__*/React.createElement(ColorscaleSelect, null), /*#__PURE__*/React.createElement(Form.Group, {
58
- className: "mb-2"
59
- }, 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
+ });
60
75
  };