@haniffalab/cherita-react 0.2.0-dev.2024-12-16.ab9c5057 → 0.2.0-dev.2024-12-16.67617f27

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 (32) hide show
  1. package/dist/components/dotplot/Dotplot.js +6 -1
  2. package/dist/components/full-page/FullPage.js +81 -7
  3. package/dist/components/heatmap/Heatmap.js +6 -1
  4. package/dist/components/matrixplot/Matrixplot.js +6 -1
  5. package/dist/components/obs-list/ObsItem.js +74 -24
  6. package/dist/components/obs-list/ObsList.js +27 -5
  7. package/dist/components/pseudospatial/Pseudospatial.js +219 -0
  8. package/dist/components/pseudospatial/PseudospatialControls.js +12 -0
  9. package/dist/components/pseudospatial/PseudospatialToolbar.js +157 -0
  10. package/dist/components/scatterplot/Scatterplot.js +100 -166
  11. package/dist/components/var-list/VarItem.js +35 -53
  12. package/dist/components/var-list/VarList.js +4 -2
  13. package/dist/components/var-list/VarSet.js +1 -0
  14. package/dist/components/violin/Violin.js +7 -2
  15. package/dist/constants/constants.js +17 -1
  16. package/dist/context/DatasetContext.js +40 -2
  17. package/dist/css/cherita.css +44 -0
  18. package/dist/css/cherita.css.map +1 -1
  19. package/dist/helpers/color-helper.js +12 -8
  20. package/dist/helpers/zarr-helper.js +2 -0
  21. package/dist/index.js +25 -0
  22. package/dist/utils/Filter.js +129 -0
  23. package/dist/utils/Histogram.js +54 -0
  24. package/dist/utils/ImageViewer.js +40 -0
  25. package/dist/{components/scatterplot → utils}/Legend.js +12 -7
  26. package/dist/utils/VirtualizedList.js +2 -2
  27. package/dist/utils/requests.js +8 -2
  28. package/dist/utils/search.js +4 -2
  29. package/dist/utils/string.js +7 -3
  30. package/package.json +2 -2
  31. package/scss/cherita.scss +44 -0
  32. package/dist/App.scss +0 -270
@@ -11,17 +11,16 @@ var _freeSolidSvgIcons = require("@fortawesome/free-solid-svg-icons");
11
11
  var _reactFontawesome = require("@fortawesome/react-fontawesome");
12
12
  var _editModes = require("@nebula.gl/edit-modes");
13
13
  var _layers2 = require("@nebula.gl/layers");
14
- var _turf = require("@turf/turf");
15
14
  var _lodash = _interopRequireDefault(require("lodash"));
16
15
  var _reactBootstrap = require("react-bootstrap");
17
- var _Legend = require("./Legend");
18
16
  var _SpatialControls = require("./SpatialControls");
19
17
  var _Toolbox = require("./Toolbox");
20
18
  var _constants = require("../../constants/constants");
21
19
  var _DatasetContext = require("../../context/DatasetContext");
22
- var _FilterContext = require("../../context/FilterContext");
23
20
  var _colorHelper = require("../../helpers/color-helper");
24
21
  var _mapHelper = require("../../helpers/map-helper");
22
+ var _Filter = require("../../utils/Filter");
23
+ var _Legend = require("../../utils/Legend");
25
24
  var _LoadingIndicators = require("../../utils/LoadingIndicators");
26
25
  var _string = require("../../utils/string");
27
26
  var _zarrData = require("../../utils/zarrData");
@@ -38,14 +37,12 @@ const INITIAL_VIEW_STATE = {
38
37
  pitch: 0,
39
38
  bearing: 0
40
39
  };
41
- const EPSILON = 1e-6;
42
40
  function Scatterplot(_ref) {
43
41
  let {
44
42
  radius = 30
45
43
  } = _ref;
46
44
  const dataset = (0, _DatasetContext.useDataset)();
47
45
  const dispatch = (0, _DatasetContext.useDatasetDispatch)();
48
- const filterDispatch = (0, _FilterContext.useFilteredDataDispatch)();
49
46
  const {
50
47
  getColor
51
48
  } = (0, _colorHelper.useColor)();
@@ -72,6 +69,12 @@ function Scatterplot(_ref) {
72
69
  const labelObsData = (0, _zarrData.useLabelObsData)();
73
70
  // @TODO: assert length of obsmData, xData, obsData is equal
74
71
 
72
+ const {
73
+ filteredIndices,
74
+ valueMin,
75
+ valueMax,
76
+ slicedLength
77
+ } = (0, _Filter.useFilter)(data, features);
75
78
  (0, _react.useEffect)(() => {
76
79
  if (!obsmData.isPending && !obsmData.serverError) {
77
80
  setIsRendering(true);
@@ -187,101 +190,6 @@ function Scatterplot(_ref) {
187
190
  return false;
188
191
  }
189
192
  }, [dataset.colorEncoding, dataset.selectedObs?.type]);
190
- const isInBins = (v, binEdges, indices) => {
191
- const lastEdge = _lodash.default.last(binEdges);
192
- const allButLastEdges = _lodash.default.initial(binEdges);
193
- // add epsilon to last edge to include the last value
194
- const modifiedBinEdges = [...allButLastEdges, [lastEdge[0], lastEdge[1] + EPSILON]];
195
- const binIndices = _lodash.default.difference(_lodash.default.range(binEdges.length), indices);
196
- const ranges = _lodash.default.at(modifiedBinEdges, binIndices);
197
- return _lodash.default.some(ranges, range => _lodash.default.inRange(v, ...range));
198
- };
199
- const isInSlice = (0, _react.useCallback)((index, values, positions) => {
200
- let inSlice = true;
201
- if (isCategorical && values) {
202
- inSlice &= !_lodash.default.includes(dataset.selectedObs?.omit, values[index]);
203
- } else if ((dataset.sliceBy.obs || dataset.colorEncoding === _constants.COLOR_ENCODINGS.OBS && dataset.selectedObs?.type === _constants.OBS_TYPES.CONTINUOUS) && !!dataset.selectedObs?.omit.length && values) {
204
- if (dataset.selectedObs.type === _constants.OBS_TYPES.CATEGORICAL) {
205
- inSlice &= !_lodash.default.includes(dataset.selectedObs.omit, values[index]);
206
- } else if (dataset.selectedObs.type === _constants.OBS_TYPES.CONTINUOUS) {
207
- if (isNaN(values[index])) {
208
- inSlice &= !_lodash.default.includes(dataset.selectedObs.omit, -1);
209
- } else {
210
- inSlice &= isInBins(values[index], dataset.selectedObs.bins.binEdges, _lodash.default.without(dataset.selectedObs.omit, -1));
211
- }
212
- }
213
- }
214
- if (dataset.sliceBy.polygons && positions) {
215
- inSlice &= _lodash.default.some(features?.features, (_f, i) => {
216
- return (0, _turf.booleanPointInPolygon)((0, _turf.point)([positions[index][0], positions[index][1]]), features.features[i]);
217
- });
218
- }
219
- return inSlice;
220
- }, [dataset.colorEncoding, dataset.selectedObs?.bins?.binEdges, dataset.selectedObs?.omit, dataset.selectedObs?.type, dataset.sliceBy.obs, dataset.sliceBy.polygons, features.features, isCategorical]);
221
-
222
- // @TODO: abstract filtering out of this component, maybe in FilterContext ?
223
- const {
224
- filteredIndices,
225
- valueMin,
226
- valueMax,
227
- slicedLength
228
- } = (0, _react.useMemo)(() => {
229
- if (dataset.colorEncoding === _constants.COLOR_ENCODINGS.VAR) {
230
- const {
231
- filtered,
232
- filteredIndices
233
- } = _lodash.default.reduce(data.values, (acc, v, i) => {
234
- if (isInSlice(i, data.sliceValues, data.positions)) {
235
- acc.filtered.push(v);
236
- acc.filteredIndices.add(i);
237
- }
238
- return acc;
239
- }, {
240
- filtered: [],
241
- filteredIndices: new Set()
242
- });
243
- return {
244
- filteredIndices: filteredIndices,
245
- valueMin: _lodash.default.min(filtered),
246
- valueMax: _lodash.default.max(filtered),
247
- slicedLength: filtered.length
248
- };
249
- } else if (dataset.colorEncoding === _constants.COLOR_ENCODINGS.OBS) {
250
- const isContinuous = dataset.selectedObs?.type === _constants.OBS_TYPES.CONTINUOUS;
251
- const {
252
- filtered,
253
- filteredIndices
254
- } = _lodash.default.reduce(data.values, (acc, v, i) => {
255
- if (isInSlice(i, data.values, data.positions)) {
256
- acc.filtered.push(v);
257
- acc.filteredIndices.add(i);
258
- }
259
- return acc;
260
- }, {
261
- filtered: [],
262
- filteredIndices: new Set()
263
- });
264
- return {
265
- filteredIndices: filteredIndices,
266
- valueMin: _lodash.default.min(isContinuous ? filtered : data.values),
267
- valueMax: _lodash.default.max(isContinuous ? filtered : data.values),
268
- slicedLength: filtered.length
269
- };
270
- } else {
271
- return {
272
- filteredIndices: null,
273
- valueMin: _lodash.default.min(data.values),
274
- valueMax: _lodash.default.max(data.values),
275
- slicedLength: data.values.length
276
- };
277
- }
278
- }, [data.positions, data.sliceValues, data.values, dataset.colorEncoding, dataset.selectedObs?.type, isInSlice]);
279
- (0, _react.useEffect)(() => {
280
- filterDispatch({
281
- type: "set.obs.indices",
282
- indices: dataset.sliceBy.obs || dataset.sliceBy.polygons ? filteredIndices : null
283
- });
284
- }, [dataset.sliceBy.obs, dataset.sliceBy.polygons, filterDispatch, filteredIndices]);
285
193
  (0, _react.useEffect)(() => {
286
194
  dispatch({
287
195
  type: "set.controls.valueRange",
@@ -300,8 +208,21 @@ function Scatterplot(_ref) {
300
208
  index
301
209
  } = _ref2;
302
210
  const grayOut = filteredIndices && !filteredIndices.has(index);
303
- return getColor((data.values[index] - min) / (max - min), isCategorical, grayOut);
211
+ return getColor({
212
+ value: (data.values[index] - min) / (max - min),
213
+ categorical: isCategorical,
214
+ grayOut: grayOut
215
+ });
304
216
  }, [data.values, filteredIndices, getColor, isCategorical, max, min]);
217
+
218
+ // @TODO: add support for pseudospatial hover to reflect in radius
219
+ const getRadius = (0, _react.useCallback)((_d, _ref3) => {
220
+ let {
221
+ index
222
+ } = _ref3;
223
+ const grayOut = filteredIndices && !filteredIndices.has(index);
224
+ return grayOut ? 1 : 3;
225
+ }, [filteredIndices]);
305
226
  const memoizedLayers = (0, _react.useMemo)(() => {
306
227
  return [new _layers.ScatterplotLayer({
307
228
  id: "cherita-layer-scatterplot",
@@ -311,21 +232,22 @@ function Scatterplot(_ref) {
311
232
  radiusMinPixels: 1,
312
233
  getPosition: d => d,
313
234
  getFillColor: getFillColor,
314
- getRadius: 1,
235
+ getRadius: getRadius,
315
236
  updateTriggers: {
316
- getFillColor: getFillColor
237
+ getFillColor: getFillColor,
238
+ getRadius: getRadius
317
239
  }
318
240
  }), new _layers2.EditableGeoJsonLayer({
319
241
  id: "cherita-layer-draw",
320
242
  data: features,
321
243
  mode: mode,
322
244
  selectedFeatureIndexes,
323
- onEdit: _ref3 => {
245
+ onEdit: _ref4 => {
324
246
  let {
325
247
  updatedData,
326
248
  editType,
327
249
  editContext
328
- } = _ref3;
250
+ } = _ref4;
329
251
  setFeatures(updatedData);
330
252
  let updatedSelectedFeatureIndexes = selectedFeatureIndexes;
331
253
  if (editType === "addFeature") {
@@ -349,7 +271,7 @@ function Scatterplot(_ref) {
349
271
  }
350
272
  }
351
273
  })];
352
- }, [data.positions, features, getFillColor, mode, radius, selectedFeatureIndexes]);
274
+ }, [data.positions, features, getFillColor, getRadius, mode, radius, selectedFeatureIndexes]);
353
275
  const layers = (0, _react.useDeferredValue)(mode === _editModes.ViewMode ? memoizedLayers.reverse() : memoizedLayers); // draw scatterplot on top of polygons when in ViewMode
354
276
 
355
277
  (0, _react.useEffect)(() => {
@@ -374,11 +296,11 @@ function Scatterplot(_ref) {
374
296
  return `${o.name}: ${o.codesMap[v]}`;
375
297
  }
376
298
  };
377
- const getTooltip = _ref4 => {
299
+ const getTooltip = _ref5 => {
378
300
  let {
379
301
  object,
380
302
  index
381
- } = _ref4;
303
+ } = _ref5;
382
304
  if (!object) return;
383
305
  const text = [];
384
306
  if (dataset.colorEncoding === _constants.COLOR_ENCODINGS.OBS && dataset.selectedObs && !_lodash.default.some(dataset.labelObs, {
@@ -396,70 +318,82 @@ function Scatterplot(_ref) {
396
318
  }));
397
319
  }
398
320
  if (!text.length) return;
321
+ const grayOut = filteredIndices && !filteredIndices.has(index);
399
322
  return {
400
- text: text.length ? _lodash.default.compact(text).join("\n") : null
323
+ text: text.length ? _lodash.default.compact(text).join("\n") : null,
324
+ className: grayOut ? "tooltip-grayout" : "deck-tooltip",
325
+ style: !grayOut ? {
326
+ "border-left": `3px solid ${(0, _colorHelper.rgbToHex)(getFillColor(null, {
327
+ index
328
+ }))}`
329
+ } : {
330
+ "border-left": "none"
331
+ }
401
332
  };
402
333
  };
403
334
  const isPending = (isRendering || xData.isPending || obsmData.isPending) && !obsmData.isPending;
404
335
  const error = dataset.selectedObsm && obsmData.serverError?.length || dataset.colorEncoding === _constants.COLOR_ENCODINGS.VAR && xData.serverError?.length || dataset.colorEncoding === _constants.COLOR_ENCODINGS.OBS && obsData.serverError?.length || dataset.labelObs.lengh && labelObsData.serverError?.length;
405
- return /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
406
- className: "cherita-scatterplot",
407
- children: [obsmData.isPending && /*#__PURE__*/(0, _jsxRuntime.jsx)(_LoadingIndicators.LoadingSpinner, {
408
- disableShrink: true
409
- }), isPending && /*#__PURE__*/(0, _jsxRuntime.jsx)(_LoadingIndicators.LoadingLinear, {}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_react2.DeckGL, {
410
- viewState: viewState,
411
- onViewStateChange: e => setViewState(e.viewState),
412
- controller: {
413
- doubleClickZoom: mode === _editModes.ViewMode
414
- },
415
- layers: layers,
416
- onClick: onLayerClick,
417
- getTooltip: getTooltip,
418
- onAfterRender: () => {
419
- setIsRendering(false);
420
- },
421
- useDevicePixels: false,
422
- getCursor: _ref5 => {
423
- let {
424
- isDragging
425
- } = _ref5;
426
- return mode !== _editModes.ViewMode ? "crosshair" : isDragging ? "grabbing" : "grab";
427
- },
428
- ref: deckRef
429
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_SpatialControls.SpatialControls, {
430
- mode: mode,
431
- setMode: setMode,
432
- features: features,
433
- setFeatures: setFeatures,
434
- selectedFeatureIndexes: selectedFeatureIndexes,
435
- resetBounds: () => setViewState(getBounds()),
436
- increaseZoom: () => setViewState(v => ({
437
- ...v,
438
- zoom: v.zoom + 1
439
- })),
440
- decreaseZoom: () => setViewState(v => ({
441
- ...v,
442
- zoom: v.zoom - 1
443
- }))
444
- }), /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
445
- className: "cherita-spatial-footer",
446
- children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
447
- className: "cherita-toolbox-footer",
448
- children: [error && !isPending && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactBootstrap.Alert, {
449
- variant: "danger",
450
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactFontawesome.FontAwesomeIcon, {
451
- icon: _freeSolidSvgIcons.faTriangleExclamation
452
- }), "\xA0Error loading data"]
453
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_Toolbox.Toolbox, {
454
- mode: dataset.colorEncoding === _constants.COLOR_ENCODINGS.VAR ? dataset.selectedVar.name : dataset.colorEncoding === _constants.COLOR_ENCODINGS.OBS ? dataset.selectedObs.name : null,
455
- obsLength: parseInt(obsmData.data?.length),
456
- slicedLength: parseInt(slicedLength)
336
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
337
+ className: "cherita-container-scatterplot",
338
+ children: /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
339
+ className: "cherita-scatterplot",
340
+ children: [obsmData.isPending && /*#__PURE__*/(0, _jsxRuntime.jsx)(_LoadingIndicators.LoadingSpinner, {
341
+ disableShrink: true
342
+ }), isPending && /*#__PURE__*/(0, _jsxRuntime.jsx)(_LoadingIndicators.LoadingLinear, {}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_react2.DeckGL, {
343
+ viewState: viewState,
344
+ onViewStateChange: e => setViewState(e.viewState),
345
+ controller: {
346
+ doubleClickZoom: mode === _editModes.ViewMode
347
+ },
348
+ layers: layers,
349
+ onClick: onLayerClick,
350
+ getTooltip: getTooltip,
351
+ onAfterRender: () => {
352
+ setIsRendering(false);
353
+ },
354
+ useDevicePixels: false,
355
+ getCursor: _ref6 => {
356
+ let {
357
+ isDragging
358
+ } = _ref6;
359
+ return mode !== _editModes.ViewMode ? "crosshair" : isDragging ? "grabbing" : "grab";
360
+ },
361
+ ref: deckRef
362
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_SpatialControls.SpatialControls, {
363
+ mode: mode,
364
+ setMode: setMode,
365
+ features: features,
366
+ setFeatures: setFeatures,
367
+ selectedFeatureIndexes: selectedFeatureIndexes,
368
+ resetBounds: () => setViewState(getBounds()),
369
+ increaseZoom: () => setViewState(v => ({
370
+ ...v,
371
+ zoom: v.zoom + 1
372
+ })),
373
+ decreaseZoom: () => setViewState(v => ({
374
+ ...v,
375
+ zoom: v.zoom - 1
376
+ }))
377
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
378
+ className: "cherita-spatial-footer",
379
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
380
+ className: "cherita-toolbox-footer",
381
+ children: [error && !isPending && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactBootstrap.Alert, {
382
+ variant: "danger",
383
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactFontawesome.FontAwesomeIcon, {
384
+ icon: _freeSolidSvgIcons.faTriangleExclamation
385
+ }), "\xA0Error loading data"]
386
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_Toolbox.Toolbox, {
387
+ mode: dataset.colorEncoding === _constants.COLOR_ENCODINGS.VAR ? dataset.selectedVar.name : dataset.colorEncoding === _constants.COLOR_ENCODINGS.OBS ? dataset.selectedObs.name : null,
388
+ obsLength: parseInt(obsmData.data?.length),
389
+ slicedLength: parseInt(slicedLength)
390
+ })]
391
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_Legend.Legend, {
392
+ isCategorical: isCategorical,
393
+ min: min,
394
+ max: max
457
395
  })]
458
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_Legend.Legend, {
459
- isCategorical: isCategorical,
460
- min: min,
461
- max: max
462
396
  })]
463
- })]
397
+ })
464
398
  });
465
399
  }
@@ -9,16 +9,13 @@ var _react = _interopRequireWildcard(require("react"));
9
9
  var _freeSolidSvgIcons = require("@fortawesome/free-solid-svg-icons");
10
10
  var _reactFontawesome = require("@fortawesome/react-fontawesome");
11
11
  var _iconsMaterial = require("@mui/icons-material");
12
- var _xCharts = require("@mui/x-charts");
13
- var _colorPalettes = require("@mui/x-charts/colorPalettes");
14
12
  var _lodash = _interopRequireDefault(require("lodash"));
15
13
  var _reactBootstrap = require("react-bootstrap");
16
14
  var _constants = require("../../constants/constants");
17
15
  var _DatasetContext = require("../../context/DatasetContext");
18
16
  var _FilterContext = require("../../context/FilterContext");
19
- var _LoadingIndicators = require("../../utils/LoadingIndicators");
17
+ var _Histogram = require("../../utils/Histogram");
20
18
  var _requests = require("../../utils/requests");
21
- var _string = require("../../utils/string");
22
19
  var _VirtualizedList = require("../../utils/VirtualizedList");
23
20
  var _jsxRuntime = require("react/jsx-runtime");
24
21
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
@@ -35,13 +32,13 @@ function VarHistogram(_ref) {
35
32
  const [params, setParams] = (0, _react.useState)({
36
33
  url: dataset.url,
37
34
  varKey: item.matrix_index,
38
- obsIndices: isSliced && Array.from(filteredData.obsIndices || [])
35
+ obsIndices: isSliced ? [...(filteredData.obsIndices || [])] : null
39
36
  });
40
37
  (0, _react.useEffect)(() => {
41
38
  setParams(p => {
42
39
  return {
43
40
  ...p,
44
- obsIndices: isSliced && Array.from(filteredData.obsIndices || [])
41
+ obsIndices: isSliced ? [...(filteredData.obsIndices || [])] : null
45
42
  };
46
43
  });
47
44
  }, [filteredData.obsIndices, isSliced]);
@@ -52,46 +49,29 @@ function VarHistogram(_ref) {
52
49
  } = (0, _requests.useDebouncedFetch)(ENDPOINT, params, {
53
50
  refetchOnMount: false
54
51
  });
55
- return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
56
- className: "feature-histogram-container",
57
- children: isPending ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_LoadingIndicators.LoadingLinear, {}) : !serverError && fetchedData ? /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
58
- className: "feature-histogram m-1",
59
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_xCharts.SparkLineChart, {
60
- plotType: "bar",
61
- data: fetchedData.log10,
62
- margin: {
63
- top: 0,
64
- right: 0,
65
- bottom: 0,
66
- left: 0
67
- },
68
- colors: isSliced ? _colorPalettes.mangoFusionPalette : _colorPalettes.blueberryTwilightPalette,
69
- showHighlight: true,
70
- showTooltip: true,
71
- valueFormatter: (v, _ref2) => {
72
- let {
73
- dataIndex
74
- } = _ref2;
75
- return `${(0, _string.formatNumerical)(fetchedData.hist[dataIndex])}`;
76
- },
77
- xAxis: {
78
- data: _lodash.default.range(fetchedData.bin_edges?.length) || null,
79
- valueFormatter: v => `Bin [${(0, _string.formatNumerical)(fetchedData.bin_edges[v][0], _string.FORMATS.EXPONENTIAL)}, ${(0, _string.formatNumerical)(fetchedData.bin_edges[v][1], _string.FORMATS.EXPONENTIAL)}${v === fetchedData.bin_edges.length - 1 ? "]" : ")"}`
80
- },
81
- slotProps: {
82
- popper: {
83
- className: "feature-histogram-tooltip"
84
- }
85
- }
86
- })
87
- }) : null
52
+ return !serverError && /*#__PURE__*/(0, _jsxRuntime.jsx)(_Histogram.Histogram, {
53
+ data: fetchedData,
54
+ isPending: isPending,
55
+ altColor: isSliced
88
56
  });
89
57
  }
90
58
  function VarDiseaseInfoItem(item) {
59
+ const dispatch = (0, _DatasetContext.useDatasetDispatch)();
91
60
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.ListGroup.Item, {
92
61
  className: "feature-disease-info",
93
62
  children: /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
94
- children: [item.disease_name, " ", /*#__PURE__*/(0, _jsxRuntime.jsx)("br", {}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Table, {
63
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("button", {
64
+ type: "button",
65
+ className: "btn btn-link",
66
+ onClick: () => {
67
+ dispatch({
68
+ type: "select.disease",
69
+ id: item.disease_id,
70
+ name: item.disease_name
71
+ });
72
+ },
73
+ children: item.disease_name
74
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)("br", {}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Table, {
95
75
  striped: true,
96
76
  children: /*#__PURE__*/(0, _jsxRuntime.jsxs)("tbody", {
97
77
  children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)("tr", {
@@ -120,25 +100,25 @@ function VarDiseaseInfoItem(item) {
120
100
  })
121
101
  })]
122
102
  })
123
- });
103
+ }, item.disease_name);
124
104
  }
125
- function VarDiseaseInfo(_ref3) {
105
+ function VarDiseaseInfo(_ref2) {
126
106
  let {
127
107
  data
128
- } = _ref3;
108
+ } = _ref2;
129
109
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(_jsxRuntime.Fragment, {
130
110
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.ListGroup, {
131
111
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_VirtualizedList.VirtualizedList, {
132
112
  getDataAtIndex: index => data[index],
133
113
  count: data.length,
134
- estimateSize: 70,
135
- maxHeight: "40vh",
114
+ estimateSize: 140,
115
+ maxHeight: "100%",
136
116
  ItemComponent: VarDiseaseInfoItem
137
117
  })
138
118
  })
139
119
  });
140
120
  }
141
- function SingleSelectionItem(_ref4) {
121
+ function SingleSelectionItem(_ref3) {
142
122
  let {
143
123
  item,
144
124
  isActive,
@@ -147,7 +127,7 @@ function SingleSelectionItem(_ref4) {
147
127
  isDiseaseGene = false,
148
128
  showSetColorEncoding = true,
149
129
  showRemove = true
150
- } = _ref4;
130
+ } = _ref3;
151
131
  const ENDPOINT = "disease/gene";
152
132
  const [openInfo, setOpenInfo] = (0, _react.useState)(false);
153
133
  const dataset = (0, _DatasetContext.useDataset)();
@@ -160,7 +140,9 @@ function SingleSelectionItem(_ref4) {
160
140
  fetchedData,
161
141
  isPending,
162
142
  serverError
163
- } = (0, _requests.useFetch)(ENDPOINT, params);
143
+ } = (0, _requests.useFetch)(ENDPOINT, params, {
144
+ refetchOnMount: false
145
+ });
164
146
  const hasDiseaseInfo = !isPending && !serverError && !!fetchedData.length;
165
147
  return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
166
148
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
@@ -207,7 +189,7 @@ function SingleSelectionItem(_ref4) {
207
189
  }), hasDiseaseInfo && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Collapse, {
208
190
  in: openInfo,
209
191
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
210
- className: "mt-2",
192
+ className: "mt-2 var-disease-info-collapse",
211
193
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(VarDiseaseInfo, {
212
194
  data: fetchedData
213
195
  })
@@ -215,12 +197,12 @@ function SingleSelectionItem(_ref4) {
215
197
  })]
216
198
  });
217
199
  }
218
- function MultipleSelectionItem(_ref5) {
200
+ function MultipleSelectionItem(_ref4) {
219
201
  let {
220
202
  item,
221
203
  isActive,
222
204
  toggleVar
223
- } = _ref5;
205
+ } = _ref4;
224
206
  const isNotInData = item.matrix_index === -1;
225
207
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(_jsxRuntime.Fragment, {
226
208
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
@@ -240,14 +222,14 @@ function MultipleSelectionItem(_ref5) {
240
222
  })
241
223
  });
242
224
  }
243
- function VarItem(_ref6) {
225
+ function VarItem(_ref5) {
244
226
  let {
245
227
  item,
246
228
  active,
247
229
  setVarButtons,
248
230
  mode = _constants.SELECTION_MODES.SINGLE,
249
231
  isDiseaseGene = false
250
- } = _ref6;
232
+ } = _ref5;
251
233
  const dataset = (0, _DatasetContext.useDataset)();
252
234
  const dispatch = (0, _DatasetContext.useDatasetDispatch)();
253
235
  const selectVar = () => {
@@ -44,7 +44,8 @@ const useVarMean = function (varKeys) {
44
44
  });
45
45
  }, [varKeys]);
46
46
  return (0, _requests.useFetch)(ENDPOINT, params, {
47
- enabled: enabled
47
+ enabled: enabled,
48
+ refetchOnMount: false
48
49
  });
49
50
  };
50
51
 
@@ -74,7 +75,8 @@ function DiseaseVarList(_ref) {
74
75
  });
75
76
  }, [dataset.selectedDisease]);
76
77
  const diseaseData = (0, _requests.useFetch)(ENDPOINT, params, {
77
- enabled: !!params.diseaseId
78
+ enabled: !!params.diseaseId,
79
+ refetchOnMount: false
78
80
  });
79
81
  (0, _react.useEffect)(() => {
80
82
  if (!diseaseData.isPending && !diseaseData.serverError) {
@@ -18,6 +18,7 @@ var _jsxRuntime = require("react/jsx-runtime");
18
18
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
19
19
  function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
20
20
  function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
21
+ // @TODO: add button to score genes and plot
21
22
  const addVarToSet = (dispatch, set, v) => {
22
23
  dispatch({
23
24
  type: "add.varSet.var",
@@ -12,6 +12,7 @@ var _reactBootstrap = require("react-bootstrap");
12
12
  var _reactPlotly = _interopRequireDefault(require("react-plotly.js"));
13
13
  var _constants = require("../../constants/constants");
14
14
  var _DatasetContext = require("../../context/DatasetContext");
15
+ var _FilterContext = require("../../context/FilterContext");
15
16
  var _LoadingIndicators = require("../../utils/LoadingIndicators");
16
17
  var _requests = require("../../utils/requests");
17
18
  var _jsxRuntime = require("react/jsx-runtime");
@@ -24,6 +25,8 @@ function Violin(_ref) {
24
25
  } = _ref;
25
26
  const ENDPOINT = "violin";
26
27
  const dataset = (0, _DatasetContext.useDataset)();
28
+ const filteredData = (0, _FilterContext.useFilteredData)();
29
+ const isSliced = dataset.sliceBy.obs || dataset.sliceBy.polygons;
27
30
  const [data, setData] = (0, _react.useState)([]);
28
31
  const [layout, setLayout] = (0, _react.useState)({});
29
32
  const [hasSelections, setHasSelections] = (0, _react.useState)(false);
@@ -46,7 +49,8 @@ function Violin(_ref) {
46
49
  indices: dataset.selectedVar?.vars.map(v => v.index)
47
50
  } : dataset.selectedVar?.index,
48
51
  obsCol: dataset.selectedObs,
49
- obsValues: !dataset.selectedObs?.omit.length ? null : _lodash.default.difference(_lodash.default.values(dataset.selectedObs?.codes), dataset.selectedObs?.omit).map(c => dataset.selectedObs?.codesMap[c])
52
+ obsValues: !dataset.selectedObs?.omit.length ? null : _lodash.default.difference(_lodash.default.values(dataset.selectedObs?.codes), dataset.selectedObs?.omit).map(c => dataset.selectedObs?.codesMap[c]),
53
+ obsIndices: isSliced ? [...(filteredData.obsIndices || [])] : null
50
54
  }
51
55
  }[mode]
52
56
  });
@@ -89,12 +93,13 @@ function Violin(_ref) {
89
93
  } : dataset.selectedVar?.index,
90
94
  obsCol: dataset.selectedObs,
91
95
  obsValues: !dataset.selectedObs?.omit.length ? null : _lodash.default.difference(_lodash.default.values(dataset.selectedObs?.codes), dataset.selectedObs?.omit).map(c => dataset.selectedObs?.codesMap[c]),
96
+ obsIndices: isSliced ? [...(filteredData.obsIndices || [])] : null,
92
97
  scale: dataset.controls.scale.violinplot.value,
93
98
  varNamesCol: dataset.varNamesCol
94
99
  };
95
100
  });
96
101
  }
97
- }, [dataset.controls.scale.violinplot.value, dataset.selectedMultiVar, dataset.selectedObs, dataset.selectedVar, dataset.url, dataset.varNamesCol, mode]);
102
+ }, [dataset.controls.scale.violinplot.value, dataset.selectedMultiVar, dataset.selectedObs, dataset.selectedVar, dataset.url, dataset.varNamesCol, filteredData.obsIndices, isSliced, mode]);
98
103
  const {
99
104
  fetchedData,
100
105
  isPending,
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.VIOLIN_MODES = exports.VIOLINPLOT_SCALES = exports.VAR_SORT_ORDER = exports.VAR_SORT = exports.UNSELECTED_POLYGON_FILLCOLOR = exports.SELECTION_MODES = exports.SELECTED_POLYGON_FILLCOLOR = exports.OBS_TYPES = exports.MATRIXPLOT_SCALES = exports.LOCAL_STORAGE_KEY = exports.DOTPLOT_SCALES = exports.COLOR_ENCODINGS = void 0;
6
+ exports.VIOLIN_MODES = exports.VIOLINPLOT_SCALES = exports.VAR_SORT_ORDER = exports.VAR_SORT = exports.UNSELECTED_POLYGON_FILLCOLOR = exports.SELECTION_MODES = exports.SELECTED_POLYGON_FILLCOLOR = exports.PSEUDOSPATIAL_PLOT_TYPES = exports.PSEUDOSPATIAL_CATEGORICAL_MODES = exports.OBS_TYPES = exports.MATRIXPLOT_SCALES = exports.LOCAL_STORAGE_KEY = exports.DOTPLOT_SCALES = exports.COLOR_ENCODINGS = void 0;
7
7
  const LOCAL_STORAGE_KEY = exports.LOCAL_STORAGE_KEY = "CHERITA";
8
8
  const COLOR_ENCODINGS = exports.COLOR_ENCODINGS = {
9
9
  VAR: "var",
@@ -71,4 +71,20 @@ const VIOLINPLOT_SCALES = exports.VIOLINPLOT_SCALES = {
71
71
  value: "count",
72
72
  name: "Count"
73
73
  }
74
+ };
75
+ const PSEUDOSPATIAL_PLOT_TYPES = exports.PSEUDOSPATIAL_PLOT_TYPES = {
76
+ GENE: "gene",
77
+ CATEGORICAL: "categorical",
78
+ CONTINUOUS: "continuous",
79
+ MASKS: "masks"
80
+ };
81
+ const PSEUDOSPATIAL_CATEGORICAL_MODES = exports.PSEUDOSPATIAL_CATEGORICAL_MODES = {
82
+ ACROSS: {
83
+ value: "across",
84
+ name: "% across sections"
85
+ },
86
+ WITHIN: {
87
+ value: "within",
88
+ name: "% within section"
89
+ }
74
90
  };