@haniffalab/cherita-react 0.2.0-dev.2024-09-26.f9979478 → 0.2.0-dev.2024-09-26.d9293c4c

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.
@@ -19,10 +19,12 @@ var _SpatialControls = require("./SpatialControls");
19
19
  var _Toolbox = require("./Toolbox");
20
20
  var _constants = require("../../constants/constants");
21
21
  var _DatasetContext = require("../../context/DatasetContext");
22
+ var _FilterContext = require("../../context/FilterContext");
22
23
  var _colorHelper = require("../../helpers/color-helper");
23
24
  var _mapHelper = require("../../helpers/map-helper");
24
25
  var _zarrHelper = require("../../helpers/zarr-helper");
25
26
  var _LoadingIndicators = require("../../utils/LoadingIndicators");
27
+ var _string = require("../../utils/string");
26
28
  var _jsxRuntime = require("react/jsx-runtime");
27
29
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
28
30
  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); }
@@ -36,16 +38,19 @@ const INITIAL_VIEW_STATE = {
36
38
  pitch: 0,
37
39
  bearing: 0
38
40
  };
41
+ const EPSILON = 1e-6;
39
42
  function Scatterplot(_ref) {
40
- var _dataset$selectedObs, _dataset$selectedObs2, _dataset$selectedObs6, _dataset$selectedObs8, _dataset$selectedObs10, _features$features2, _obsmData$serverError, _xData$serverError, _obsData$serverError, _labelObsData$serverE, _obsmData$data;
43
+ var _dataset$selectedObs, _dataset$selectedObs2, _dataset$selectedObs7, _dataset$selectedObs11, _dataset$selectedObs12, _dataset$selectedObs13, _dataset$selectedObs15, _features$features2, _obsmData$serverError, _xData$serverError, _obsData$serverError, _labelObsData$serverE, _obsmData$data;
41
44
  let {
42
45
  radius = 30
43
46
  } = _ref;
44
47
  const dataset = (0, _DatasetContext.useDataset)();
45
48
  const dispatch = (0, _DatasetContext.useDatasetDispatch)();
49
+ const filterDispatch = (0, _FilterContext.useFilteredDataDispatch)();
46
50
  const {
47
51
  getColor
48
52
  } = (0, _colorHelper.useColor)();
53
+ const deckRef = (0, _react.useRef)(null);
49
54
  const [viewState, setViewState] = (0, _react.useState)(INITIAL_VIEW_STATE);
50
55
  const [isRendering, setIsRendering] = (0, _react.useState)(true);
51
56
  const [data, setData] = (0, _react.useState)({
@@ -72,7 +77,7 @@ function Scatterplot(_ref) {
72
77
  });
73
78
  const [obsParams, setObsParams] = (0, _react.useState)({
74
79
  url: dataset.url,
75
- path: "obs/" + ((_dataset$selectedObs = dataset.selectedObs) === null || _dataset$selectedObs === void 0 ? void 0 : _dataset$selectedObs.name) + (((_dataset$selectedObs2 = dataset.selectedObs) === null || _dataset$selectedObs2 === void 0 ? void 0 : _dataset$selectedObs2.type) === _constants.OBS_TYPES.CONTINUOUS ? "" : "/codes")
80
+ path: "obs/" + ((_dataset$selectedObs = dataset.selectedObs) === null || _dataset$selectedObs === void 0 ? void 0 : _dataset$selectedObs.name) + (((_dataset$selectedObs2 = dataset.selectedObs) === null || _dataset$selectedObs2 === void 0 ? void 0 : _dataset$selectedObs2.type) === _constants.OBS_TYPES.CATEGORICAL ? "/codes" : "")
76
81
  });
77
82
  const [labelObsParams, setLabelObsParams] = (0, _react.useState)([]);
78
83
 
@@ -107,7 +112,7 @@ function Scatterplot(_ref) {
107
112
  var _dataset$selectedObs3, _dataset$selectedObs4;
108
113
  return {
109
114
  ...p,
110
- path: "obs/" + ((_dataset$selectedObs3 = dataset.selectedObs) === null || _dataset$selectedObs3 === void 0 ? void 0 : _dataset$selectedObs3.name) + (((_dataset$selectedObs4 = dataset.selectedObs) === null || _dataset$selectedObs4 === void 0 ? void 0 : _dataset$selectedObs4.type) === _constants.OBS_TYPES.CONTINUOUS ? "" : "/codes")
115
+ path: "obs/" + ((_dataset$selectedObs3 = dataset.selectedObs) === null || _dataset$selectedObs3 === void 0 ? void 0 : _dataset$selectedObs3.name) + (((_dataset$selectedObs4 = dataset.selectedObs) === null || _dataset$selectedObs4 === void 0 ? void 0 : _dataset$selectedObs4.type) === _constants.OBS_TYPES.CATEGORICAL ? "/codes" : "")
111
116
  };
112
117
  });
113
118
  }, [dataset.selectedObs]);
@@ -115,7 +120,7 @@ function Scatterplot(_ref) {
115
120
  setLabelObsParams(_lodash.default.map(dataset.labelObs, obs => {
116
121
  return {
117
122
  url: dataset.url,
118
- path: "obs/" + obs.name + (obs.type === _constants.OBS_TYPES.CONTINUOUS ? "" : "/codes"),
123
+ path: "obs/" + obs.name + (obs.type === _constants.OBS_TYPES.CATEGORICAL ? "/codes" : ""),
119
124
  key: obs.name
120
125
  };
121
126
  }));
@@ -145,6 +150,7 @@ function Scatterplot(_ref) {
145
150
 
146
151
  (0, _react.useEffect)(() => {
147
152
  if (!obsmData.isPending && !obsmData.serverError) {
153
+ var _deckRef$current, _deckRef$current2;
148
154
  setIsRendering(true);
149
155
  setData(d => {
150
156
  return {
@@ -157,7 +163,10 @@ function Scatterplot(_ref) {
157
163
  latitude,
158
164
  longitude,
159
165
  zoom
160
- } = mapHelper.fitBounds(obsmData.data);
166
+ } = mapHelper.fitBounds(obsmData.data, {
167
+ width: deckRef === null || deckRef === void 0 || (_deckRef$current = deckRef.current) === null || _deckRef$current === void 0 || (_deckRef$current = _deckRef$current.deck) === null || _deckRef$current === void 0 ? void 0 : _deckRef$current.width,
168
+ height: deckRef === null || deckRef === void 0 || (_deckRef$current2 = deckRef.current) === null || _deckRef$current2 === void 0 || (_deckRef$current2 = _deckRef$current2.deck) === null || _deckRef$current2 === void 0 ? void 0 : _deckRef$current2.height
169
+ });
161
170
  setViewState(v => {
162
171
  return {
163
172
  ...v,
@@ -176,12 +185,16 @@ function Scatterplot(_ref) {
176
185
  });
177
186
  }
178
187
  }, [dataset.selectedObsm, obsmData.data, obsmData.isPending, obsmData.serverError]);
179
- const bounds = (0, _react.useMemo)(() => {
188
+ const getBounds = (0, _react.useCallback)(() => {
189
+ var _deckRef$current3, _deckRef$current4;
180
190
  const {
181
191
  latitude,
182
192
  longitude,
183
193
  zoom
184
- } = new _mapHelper.MapHelper().fitBounds(data.positions);
194
+ } = new _mapHelper.MapHelper().fitBounds(data.positions, {
195
+ width: deckRef === null || deckRef === void 0 || (_deckRef$current3 = deckRef.current) === null || _deckRef$current3 === void 0 || (_deckRef$current3 = _deckRef$current3.deck) === null || _deckRef$current3 === void 0 ? void 0 : _deckRef$current3.width,
196
+ height: deckRef === null || deckRef === void 0 || (_deckRef$current4 = deckRef.current) === null || _deckRef$current4 === void 0 || (_deckRef$current4 = _deckRef$current4.deck) === null || _deckRef$current4 === void 0 ? void 0 : _deckRef$current4.height
197
+ });
185
198
  return {
186
199
  latitude,
187
200
  longitude,
@@ -247,17 +260,37 @@ function Scatterplot(_ref) {
247
260
  }, [dataset.colorEncoding, obsData.data, obsData.isPending, obsData.serverError, dataset.sliceBy.obs]);
248
261
  const isCategorical = (0, _react.useMemo)(() => {
249
262
  if (dataset.colorEncoding === _constants.COLOR_ENCODINGS.OBS) {
250
- var _dataset$selectedObs5;
251
- return ((_dataset$selectedObs5 = dataset.selectedObs) === null || _dataset$selectedObs5 === void 0 ? void 0 : _dataset$selectedObs5.type) === _constants.OBS_TYPES.CATEGORICAL;
263
+ var _dataset$selectedObs5, _dataset$selectedObs6;
264
+ return ((_dataset$selectedObs5 = dataset.selectedObs) === null || _dataset$selectedObs5 === void 0 ? void 0 : _dataset$selectedObs5.type) === _constants.OBS_TYPES.CATEGORICAL || ((_dataset$selectedObs6 = dataset.selectedObs) === null || _dataset$selectedObs6 === void 0 ? void 0 : _dataset$selectedObs6.type) === _constants.OBS_TYPES.BOOLEAN;
252
265
  } else {
253
266
  return false;
254
267
  }
255
- }, [dataset.colorEncoding, (_dataset$selectedObs6 = dataset.selectedObs) === null || _dataset$selectedObs6 === void 0 ? void 0 : _dataset$selectedObs6.type]);
268
+ }, [dataset.colorEncoding, (_dataset$selectedObs7 = dataset.selectedObs) === null || _dataset$selectedObs7 === void 0 ? void 0 : _dataset$selectedObs7.type]);
269
+ const isInBins = (v, binEdges, indices) => {
270
+ const lastEdge = _lodash.default.last(binEdges);
271
+ const allButLastEdges = _lodash.default.initial(binEdges);
272
+ // add epsilon to last edge to include the last value
273
+ const modifiedBinEdges = [...allButLastEdges, [lastEdge[0], lastEdge[1] + EPSILON]];
274
+ const binIndices = _lodash.default.difference(_lodash.default.range(binEdges.length), indices);
275
+ const ranges = _lodash.default.at(modifiedBinEdges, binIndices);
276
+ return _lodash.default.some(ranges, range => _lodash.default.inRange(v, ...range));
277
+ };
256
278
  const isInSlice = (0, _react.useCallback)((index, values, positions) => {
279
+ var _dataset$selectedObs9, _dataset$selectedObs10;
257
280
  let inSlice = true;
258
- if ((dataset.sliceBy.obs || isCategorical) && values) {
259
- var _dataset$selectedObs7;
260
- inSlice &= !_lodash.default.includes((_dataset$selectedObs7 = dataset.selectedObs) === null || _dataset$selectedObs7 === void 0 ? void 0 : _dataset$selectedObs7.omit, values[index]);
281
+ if (isCategorical && values) {
282
+ var _dataset$selectedObs8;
283
+ inSlice &= !_lodash.default.includes((_dataset$selectedObs8 = dataset.selectedObs) === null || _dataset$selectedObs8 === void 0 ? void 0 : _dataset$selectedObs8.omit, values[index]);
284
+ } else if ((dataset.sliceBy.obs || dataset.colorEncoding === _constants.COLOR_ENCODINGS.OBS && ((_dataset$selectedObs9 = dataset.selectedObs) === null || _dataset$selectedObs9 === void 0 ? void 0 : _dataset$selectedObs9.type) === _constants.OBS_TYPES.CONTINUOUS) && !!((_dataset$selectedObs10 = dataset.selectedObs) !== null && _dataset$selectedObs10 !== void 0 && _dataset$selectedObs10.omit.length) && values) {
285
+ if (dataset.selectedObs.type === _constants.OBS_TYPES.CATEGORICAL) {
286
+ inSlice &= !_lodash.default.includes(dataset.selectedObs.omit, values[index]);
287
+ } else if (dataset.selectedObs.type === _constants.OBS_TYPES.CONTINUOUS) {
288
+ if (Number.isNaN(values[index])) {
289
+ inSlice &= !_lodash.default.includes(dataset.selectedObs.omit, -1);
290
+ } else {
291
+ inSlice &= isInBins(values[index], dataset.selectedObs.bins.binEdges, _lodash.default.without(dataset.selectedObs.omit, -1));
292
+ }
293
+ }
261
294
  }
262
295
  if (dataset.sliceBy.polygons && positions) {
263
296
  inSlice &= _lodash.default.some(features === null || features === void 0 ? void 0 : features.features, (_f, i) => {
@@ -265,7 +298,7 @@ function Scatterplot(_ref) {
265
298
  });
266
299
  }
267
300
  return inSlice;
268
- }, [(_dataset$selectedObs8 = dataset.selectedObs) === null || _dataset$selectedObs8 === void 0 ? void 0 : _dataset$selectedObs8.omit, dataset.sliceBy.obs, dataset.sliceBy.polygons, features.features, isCategorical]);
301
+ }, [dataset.colorEncoding, (_dataset$selectedObs11 = dataset.selectedObs) === null || _dataset$selectedObs11 === void 0 || (_dataset$selectedObs11 = _dataset$selectedObs11.bins) === null || _dataset$selectedObs11 === void 0 ? void 0 : _dataset$selectedObs11.binEdges, (_dataset$selectedObs12 = dataset.selectedObs) === null || _dataset$selectedObs12 === void 0 ? void 0 : _dataset$selectedObs12.omit, (_dataset$selectedObs13 = dataset.selectedObs) === null || _dataset$selectedObs13 === void 0 ? void 0 : _dataset$selectedObs13.type, dataset.sliceBy.obs, dataset.sliceBy.polygons, features.features, isCategorical]);
269
302
  const {
270
303
  filteredIndices,
271
304
  valueMin,
@@ -293,8 +326,8 @@ function Scatterplot(_ref) {
293
326
  slicedLength: filtered.length
294
327
  };
295
328
  } else if (dataset.colorEncoding === _constants.COLOR_ENCODINGS.OBS) {
296
- var _dataset$selectedObs9;
297
- const isContinuous = ((_dataset$selectedObs9 = dataset.selectedObs) === null || _dataset$selectedObs9 === void 0 ? void 0 : _dataset$selectedObs9.type) === _constants.OBS_TYPES.CONTINUOUS;
329
+ var _dataset$selectedObs14;
330
+ const isContinuous = ((_dataset$selectedObs14 = dataset.selectedObs) === null || _dataset$selectedObs14 === void 0 ? void 0 : _dataset$selectedObs14.type) === _constants.OBS_TYPES.CONTINUOUS;
298
331
  const {
299
332
  filtered,
300
333
  filteredIndices
@@ -322,7 +355,13 @@ function Scatterplot(_ref) {
322
355
  slicedLength: data.values.length
323
356
  };
324
357
  }
325
- }, [data.positions, data.sliceValues, data.values, dataset.colorEncoding, (_dataset$selectedObs10 = dataset.selectedObs) === null || _dataset$selectedObs10 === void 0 ? void 0 : _dataset$selectedObs10.type, isInSlice]);
358
+ }, [data.positions, data.sliceValues, data.values, dataset.colorEncoding, (_dataset$selectedObs15 = dataset.selectedObs) === null || _dataset$selectedObs15 === void 0 ? void 0 : _dataset$selectedObs15.type, isInSlice]);
359
+ (0, _react.useEffect)(() => {
360
+ filterDispatch({
361
+ type: "set.obs.indices",
362
+ indices: dataset.sliceBy.obs || dataset.sliceBy.polygons ? filteredIndices : null
363
+ });
364
+ }, [dataset.sliceBy.obs, dataset.sliceBy.polygons, filterDispatch, filteredIndices]);
326
365
  (0, _react.useEffect)(() => {
327
366
  dispatch({
328
367
  type: "set.controls.valueRange",
@@ -408,20 +447,40 @@ function Scatterplot(_ref) {
408
447
  }
409
448
  setSelectedFeatureIndexes(f => info.object ? info.layer.id === "cherita-layer-draw" ? [info.index] : f : []);
410
449
  }
450
+ const getLabel = function (o, v) {
451
+ let isVar = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
452
+ if (isVar || o.type === _constants.OBS_TYPES.CONTINUOUS) {
453
+ return "".concat(o.name, ": ").concat((0, _string.prettyNumerical)(parseFloat(v)));
454
+ } else {
455
+ return "".concat(o.name, ": ").concat(o.codesMap[v]);
456
+ }
457
+ };
411
458
  const getTooltip = _ref4 => {
412
459
  let {
413
460
  object,
414
461
  index
415
462
  } = _ref4;
416
- return object && dataset.labelObs.length && {
417
- text: _lodash.default.map(labelObsData, (v, k) => {
463
+ if (!object) return;
464
+ const text = [];
465
+ if (dataset.colorEncoding === _constants.COLOR_ENCODINGS.OBS && dataset.selectedObs && !_lodash.default.some(dataset.labelObs, {
466
+ name: dataset.selectedObs.name
467
+ })) {
468
+ var _obsData$data;
469
+ text.push(getLabel(dataset.selectedObs, (_obsData$data = obsData.data) === null || _obsData$data === void 0 ? void 0 : _obsData$data[index]));
470
+ }
471
+ if (dataset.colorEncoding === _constants.COLOR_ENCODINGS.VAR && dataset.selectedVar) {
472
+ var _xData$data;
473
+ text.push(getLabel(dataset.selectedVar, (_xData$data = xData.data) === null || _xData$data === void 0 ? void 0 : _xData$data[index], true));
474
+ }
475
+ if (dataset.labelObs.length) {
476
+ text.push(..._lodash.default.map(labelObsData, (v, k) => {
418
477
  const labelObs = _lodash.default.find(dataset.labelObs, o => o.name === k);
419
- if (labelObs.type === _constants.OBS_TYPES.CONTINUOUS) {
420
- return "".concat(k, ": ").concat(parseFloat(v === null || v === void 0 ? void 0 : v[index]).toLocaleString());
421
- } else {
422
- return "".concat(k, ": ").concat(labelObs.codesMap[v === null || v === void 0 ? void 0 : v[index]]);
423
- }
424
- }).join("\n")
478
+ return getLabel(labelObs, v[index]);
479
+ }));
480
+ }
481
+ if (!text.length) return;
482
+ return {
483
+ text: text.length ? _lodash.default.compact(text).join("\n") : null
425
484
  };
426
485
  };
427
486
  const isPending = (isRendering || xData.isPending || obsmData.isPending) && !obsmData.isPending;
@@ -448,14 +507,15 @@ function Scatterplot(_ref) {
448
507
  isDragging
449
508
  } = _ref5;
450
509
  return mode !== _editModes.ViewMode ? "crosshair" : isDragging ? "grabbing" : "grab";
451
- }
510
+ },
511
+ ref: deckRef
452
512
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_SpatialControls.SpatialControls, {
453
513
  mode: mode,
454
514
  setMode: setMode,
455
515
  features: features,
456
516
  setFeatures: setFeatures,
457
517
  selectedFeatureIndexes: selectedFeatureIndexes,
458
- resetBounds: () => setViewState(bounds),
518
+ resetBounds: () => setViewState(getBounds()),
459
519
  increaseZoom: () => setViewState(v => ({
460
520
  ...v,
461
521
  zoom: v.zoom + 1
@@ -464,20 +524,20 @@ function Scatterplot(_ref) {
464
524
  ...v,
465
525
  zoom: v.zoom - 1
466
526
  }))
467
- }), error && !isPending && /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
468
- className: "cherita-alert",
469
- children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactBootstrap.Alert, {
470
- variant: "danger",
471
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactFontawesome.FontAwesomeIcon, {
472
- icon: _freeSolidSvgIcons.faTriangleExclamation
473
- }), "Error loading data"]
474
- })
475
527
  }), /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
476
528
  className: "cherita-spatial-footer",
477
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_Toolbox.Toolbox, {
478
- mode: dataset.colorEncoding === _constants.COLOR_ENCODINGS.VAR ? dataset.selectedVar.name : dataset.colorEncoding === _constants.COLOR_ENCODINGS.OBS ? dataset.selectedObs.name : null,
479
- obsLength: parseInt((_obsmData$data = obsmData.data) === null || _obsmData$data === void 0 ? void 0 : _obsmData$data.length),
480
- slicedLength: parseInt(slicedLength)
529
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
530
+ className: "cherita-toolbox-footer",
531
+ children: [error && !isPending && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactBootstrap.Alert, {
532
+ variant: "danger",
533
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactFontawesome.FontAwesomeIcon, {
534
+ icon: _freeSolidSvgIcons.faTriangleExclamation
535
+ }), "\xA0Error loading data"]
536
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_Toolbox.Toolbox, {
537
+ mode: dataset.colorEncoding === _constants.COLOR_ENCODINGS.VAR ? dataset.selectedVar.name : dataset.colorEncoding === _constants.COLOR_ENCODINGS.OBS ? dataset.selectedObs.name : null,
538
+ obsLength: parseInt((_obsmData$data = obsmData.data) === null || _obsmData$data === void 0 ? void 0 : _obsmData$data.length),
539
+ slicedLength: parseInt(slicedLength)
540
+ })]
481
541
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_Legend.Legend, {
482
542
  isCategorical: isCategorical,
483
543
  min: min,
@@ -9,6 +9,7 @@ var _freeSolidSvgIcons = require("@fortawesome/free-solid-svg-icons");
9
9
  var _reactFontawesome = require("@fortawesome/react-fontawesome");
10
10
  var _Button = _interopRequireDefault(require("react-bootstrap/Button"));
11
11
  var _ButtonGroup = _interopRequireDefault(require("react-bootstrap/ButtonGroup"));
12
+ var _string = require("../../utils/string");
12
13
  var _ObsmList = require("../obsm-list/ObsmList");
13
14
  var _jsxRuntime = require("react/jsx-runtime");
14
15
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
@@ -28,10 +29,10 @@ function Toolbox(_ref) {
28
29
  }), " ", mode]
29
30
  }), (mode || !Number.isNaN(obsLength)) && (mode !== null && !Number.isNaN(slicedLength) && slicedLength !== obsLength ? /*#__PURE__*/(0, _jsxRuntime.jsxs)(_Button.default, {
30
31
  size: "sm",
31
- children: [slicedLength.toLocaleString(), " out of", " ", obsLength.toLocaleString(), " cells"]
32
+ children: [(0, _string.prettyNumerical)(slicedLength), " out of", " ", (0, _string.prettyNumerical)(obsLength), " cells"]
32
33
  }) : /*#__PURE__*/(0, _jsxRuntime.jsxs)(_Button.default, {
33
34
  size: "sm",
34
- children: [obsLength.toLocaleString(), " cells"]
35
+ children: [(0, _string.prettyNumerical)(obsLength), " cells"]
35
36
  }))]
36
37
  })
37
38
  });
@@ -0,0 +1,313 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.VarItem = VarItem;
7
+ var _react = _interopRequireWildcard(require("react"));
8
+ var _freeSolidSvgIcons = require("@fortawesome/free-solid-svg-icons");
9
+ var _reactFontawesome = require("@fortawesome/react-fontawesome");
10
+ var _iconsMaterial = require("@mui/icons-material");
11
+ var _xCharts = require("@mui/x-charts");
12
+ var _colorPalettes = require("@mui/x-charts/colorPalettes");
13
+ var _lodash = _interopRequireDefault(require("lodash"));
14
+ var _reactBootstrap = require("react-bootstrap");
15
+ var _constants = require("../../constants/constants");
16
+ var _DatasetContext = require("../../context/DatasetContext");
17
+ var _FilterContext = require("../../context/FilterContext");
18
+ var _LoadingIndicators = require("../../utils/LoadingIndicators");
19
+ var _requests = require("../../utils/requests");
20
+ var _string = require("../../utils/string");
21
+ var _VirtualizedList = require("../../utils/VirtualizedList");
22
+ var _jsxRuntime = require("react/jsx-runtime");
23
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
24
+ 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); }
25
+ 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; }
26
+ function VarHistogram(_ref) {
27
+ var _fetchedData$bin_edge;
28
+ let {
29
+ item
30
+ } = _ref;
31
+ const ENDPOINT = "var/histograms";
32
+ const dataset = (0, _DatasetContext.useDataset)();
33
+ const filteredData = (0, _FilterContext.useFilteredData)();
34
+ const isSliced = dataset.sliceBy.obs || dataset.sliceBy.polygons;
35
+ const [params, setParams] = (0, _react.useState)({
36
+ url: dataset.url,
37
+ var_index: item.matrix_index,
38
+ obs_indices: isSliced && Array.from(filteredData.obsIndices || [])
39
+ });
40
+ (0, _react.useEffect)(() => {
41
+ setParams(p => {
42
+ return {
43
+ ...p,
44
+ obs_indices: isSliced && Array.from(filteredData.obsIndices || [])
45
+ };
46
+ });
47
+ }, [filteredData.obsIndices, isSliced]);
48
+ const {
49
+ fetchedData,
50
+ isPending,
51
+ serverError
52
+ } = (0, _requests.useDebouncedFetch)(ENDPOINT, params, {
53
+ refetchOnMount: false
54
+ });
55
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
56
+ className: "feature-histogram-container m-2",
57
+ children: isPending ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_LoadingIndicators.LoadingLinear, {}) : !serverError && fetchedData ? /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
58
+ className: "feature-histogram",
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 "".concat((0, _string.prettyNumerical)(fetchedData.hist[dataIndex]));
76
+ },
77
+ xAxis: {
78
+ data: _lodash.default.range((_fetchedData$bin_edge = fetchedData.bin_edges) === null || _fetchedData$bin_edge === void 0 ? void 0 : _fetchedData$bin_edge.length) || null,
79
+ valueFormatter: v => "Bin [".concat((0, _string.prettyNumerical)(fetchedData.bin_edges[v][0]), ", ").concat((0, _string.prettyNumerical)(fetchedData.bin_edges[v][1])).concat(v === fetchedData.bin_edges.length - 1 ? "]" : ")")
80
+ },
81
+ slotProps: {
82
+ popper: {
83
+ className: "feature-histogram-tooltip"
84
+ }
85
+ }
86
+ })
87
+ }) : null
88
+ });
89
+ }
90
+ function VarDiseaseInfoItem(item) {
91
+ var _item$metadata;
92
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.ListGroup.Item, {
93
+ className: "feature-disease-info",
94
+ children: /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
95
+ children: [item.disease_name, " ", /*#__PURE__*/(0, _jsxRuntime.jsx)("br", {}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Table, {
96
+ striped: true,
97
+ children: /*#__PURE__*/(0, _jsxRuntime.jsxs)("tbody", {
98
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)("tr", {
99
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("td", {
100
+ children: "Confidence"
101
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)("td", {
102
+ children: item.confidence || "unknown"
103
+ })]
104
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)("tr", {
105
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)("td", {
106
+ children: ["Organ", item.organs.length > 1 ? "s" : ""]
107
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)("td", {
108
+ children: item.organs.map(o => o.name).join(", ")
109
+ })]
110
+ }), !!((_item$metadata = item.metadata) !== null && _item$metadata !== void 0 && _item$metadata.length) && item.metadata.map(m => {
111
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)("tr", {
112
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("td", {
113
+ children: m.key
114
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)("td", {
115
+ children: m.value
116
+ })]
117
+ });
118
+ })]
119
+ })
120
+ })]
121
+ })
122
+ });
123
+ }
124
+ function VarDiseaseInfo(_ref3) {
125
+ let {
126
+ data
127
+ } = _ref3;
128
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_jsxRuntime.Fragment, {
129
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.ListGroup, {
130
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_VirtualizedList.VirtualizedList, {
131
+ getDataAtIndex: index => data[index],
132
+ count: data.length,
133
+ estimateSize: 70,
134
+ maxHeight: "40vh",
135
+ ItemComponent: VarDiseaseInfoItem
136
+ })
137
+ })
138
+ });
139
+ }
140
+ function SingleSelectionItem(_ref4) {
141
+ let {
142
+ item,
143
+ isActive,
144
+ selectVar,
145
+ removeVar,
146
+ isDiseaseGene
147
+ } = _ref4;
148
+ const ENDPOINT = "disease/gene";
149
+ const [openInfo, setOpenInfo] = (0, _react.useState)(false);
150
+ const dataset = (0, _DatasetContext.useDataset)();
151
+ const params = {
152
+ geneName: item.name,
153
+ diseaseDatasets: dataset.diseaseDatasets
154
+ };
155
+ const isNotInData = item.matrix_index === -1;
156
+ const {
157
+ fetchedData,
158
+ isPending,
159
+ serverError
160
+ } = (0, _requests.useFetch)(ENDPOINT, params);
161
+ const hasDiseaseInfo = !isPending && !serverError && !!fetchedData.length;
162
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
163
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
164
+ className: "d-flex justify-content-between ".concat(hasDiseaseInfo ? "cursor-pointer" : ""),
165
+ onClick: () => {
166
+ setOpenInfo(o => !o);
167
+ },
168
+ children: /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
169
+ className: "d-flex justify-content-between align-items-center w-100",
170
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
171
+ children: item.name
172
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
173
+ className: "d-flex align-items-center gap-1",
174
+ children: [hasDiseaseInfo && /*#__PURE__*/(0, _jsxRuntime.jsx)(_iconsMaterial.MoreVert, {}), !isDiseaseGene && /*#__PURE__*/(0, _jsxRuntime.jsx)(VarHistogram, {
175
+ item: item
176
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Button, {
177
+ type: "button",
178
+ variant: isActive ? "primary" : isNotInData ? "outline-secondary" : "outline-primary",
179
+ className: "m-0 p-0 px-1",
180
+ onClick: e => {
181
+ e.stopPropagation();
182
+ selectVar();
183
+ },
184
+ disabled: isNotInData,
185
+ title: isNotInData ? "Not present in data" : "Set as color encoding",
186
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactFontawesome.FontAwesomeIcon, {
187
+ icon: _freeSolidSvgIcons.faDroplet
188
+ })
189
+ }, item.matrix_index), !isDiseaseGene && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Button, {
190
+ type: "button",
191
+ className: "m-0 p-0 px-1",
192
+ variant: "outline-secondary",
193
+ title: "Remove from list",
194
+ onClick: e => {
195
+ e.stopPropagation();
196
+ removeVar();
197
+ },
198
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactFontawesome.FontAwesomeIcon, {
199
+ icon: _freeSolidSvgIcons.faTrash
200
+ })
201
+ })]
202
+ })]
203
+ })
204
+ }), hasDiseaseInfo && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Collapse, {
205
+ in: openInfo,
206
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
207
+ className: "mt-2",
208
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(VarDiseaseInfo, {
209
+ data: fetchedData
210
+ })
211
+ })
212
+ })]
213
+ });
214
+ }
215
+ function MultipleSelectionItem(_ref5) {
216
+ let {
217
+ item,
218
+ isActive,
219
+ toggleVar
220
+ } = _ref5;
221
+ const isNotInData = item.matrix_index === -1;
222
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_jsxRuntime.Fragment, {
223
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
224
+ className: "d-flex",
225
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
226
+ className: "flex-grow-1",
227
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Button, {
228
+ type: "button",
229
+ variant: isActive ? "primary" : "outline-primary",
230
+ className: "m-0 p-0 px-1",
231
+ onClick: toggleVar,
232
+ disabled: isNotInData,
233
+ title: isNotInData ? "Not present in data" : "",
234
+ children: item.name
235
+ }, item.matrix_index)
236
+ })
237
+ })
238
+ });
239
+ }
240
+ function VarItem(_ref6) {
241
+ let {
242
+ item,
243
+ active,
244
+ setVarButtons,
245
+ mode = _constants.SELECTION_MODES.SINGLE,
246
+ isDiseaseGene = false
247
+ } = _ref6;
248
+ const dataset = (0, _DatasetContext.useDataset)();
249
+ const dispatch = (0, _DatasetContext.useDatasetDispatch)();
250
+ const selectVar = v => {
251
+ if (mode === _constants.SELECTION_MODES.SINGLE) {
252
+ dispatch({
253
+ type: "select.var",
254
+ var: v
255
+ });
256
+ dispatch({
257
+ type: "set.colorEncoding",
258
+ value: "var"
259
+ });
260
+ } else if (mode === _constants.SELECTION_MODES.MULTIPLE) {
261
+ dispatch({
262
+ type: "select.multivar",
263
+ var: v
264
+ });
265
+ }
266
+ };
267
+ const removeVar = v => {
268
+ setVarButtons(b => {
269
+ return b.filter(i => i.name !== v.name);
270
+ });
271
+ if (mode === _constants.SELECTION_MODES.SINGLE) {
272
+ if (active === v.matrix_index) {
273
+ dispatch({
274
+ type: "deselect.var"
275
+ });
276
+ }
277
+ } else if (mode === _constants.SELECTION_MODES.MULTIPLE) {
278
+ if (active.includes(v.matrix_index)) {
279
+ dispatch({
280
+ type: "deselect.multivar",
281
+ var: v
282
+ });
283
+ }
284
+ }
285
+ };
286
+ const toggleVar = v => {
287
+ if (active.includes(v.matrix_index)) {
288
+ dispatch({
289
+ type: "deselect.multivar",
290
+ var: v
291
+ });
292
+ } else {
293
+ selectVar(v);
294
+ }
295
+ };
296
+ if (item && mode === _constants.SELECTION_MODES.SINGLE) {
297
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(SingleSelectionItem, {
298
+ item: item,
299
+ isActive: dataset.colorEncoding === _constants.COLOR_ENCODINGS.VAR && active === item.matrix_index,
300
+ selectVar: () => selectVar(item),
301
+ removeVar: () => removeVar(item),
302
+ isDiseaseGene: isDiseaseGene
303
+ });
304
+ } else if (mode === _constants.SELECTION_MODES.MULTIPLE) {
305
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(MultipleSelectionItem, {
306
+ item: item,
307
+ isActive: item.matrix_index !== -1 && _lodash.default.includes(active, item.matrix_index),
308
+ toggleVar: () => toggleVar(item)
309
+ });
310
+ } else {
311
+ return null;
312
+ }
313
+ }