@haniffalab/cherita-react 0.2.0-dev.2024-12-16.f6e39628 → 0.2.0-dev.2024-12-16.f02cfae4

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.
@@ -14,7 +14,6 @@ var _layers2 = require("@nebula.gl/layers");
14
14
  var _turf = require("@turf/turf");
15
15
  var _lodash = _interopRequireDefault(require("lodash"));
16
16
  var _reactBootstrap = require("react-bootstrap");
17
- var _Legend = require("./Legend");
18
17
  var _SpatialControls = require("./SpatialControls");
19
18
  var _Toolbox = require("./Toolbox");
20
19
  var _constants = require("../../constants/constants");
@@ -22,9 +21,10 @@ var _DatasetContext = require("../../context/DatasetContext");
22
21
  var _FilterContext = require("../../context/FilterContext");
23
22
  var _colorHelper = require("../../helpers/color-helper");
24
23
  var _mapHelper = require("../../helpers/map-helper");
25
- var _zarrHelper = require("../../helpers/zarr-helper");
24
+ var _Legend = require("../../utils/Legend");
26
25
  var _LoadingIndicators = require("../../utils/LoadingIndicators");
27
26
  var _string = require("../../utils/string");
27
+ var _zarrData = require("../../utils/zarrData");
28
28
  var _jsxRuntime = require("react/jsx-runtime");
29
29
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
30
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); }
@@ -39,14 +39,6 @@ const INITIAL_VIEW_STATE = {
39
39
  bearing: 0
40
40
  };
41
41
  const EPSILON = 1e-6;
42
- const meanData = (_i, data) => {
43
- return _lodash.default.zipWith(...data, function () {
44
- for (var _len = arguments.length, values = new Array(_len), _key = 0; _key < _len; _key++) {
45
- values[_key] = arguments[_key];
46
- }
47
- return _lodash.default.mean(values);
48
- });
49
- };
50
42
  function Scatterplot(_ref) {
51
43
  let {
52
44
  radius = 30
@@ -74,83 +66,10 @@ function Scatterplot(_ref) {
74
66
  features: []
75
67
  });
76
68
  const [selectedFeatureIndexes, setSelectedFeatureIndexes] = (0, _react.useState)([]);
77
- const [obsmParams, setObsmParams] = (0, _react.useState)({
78
- url: dataset.url,
79
- path: "obsm/" + dataset.selectedObsm
80
- });
81
- const [xParams, setXParams] = (0, _react.useState)(!dataset.selectedVar ? [] : !dataset.selectedVar?.isSet ? [{
82
- url: dataset.url,
83
- path: "X",
84
- s: [null, dataset.selectedVar?.matrix_index]
85
- }] : _lodash.default.map(dataset.selectedVar?.vars, v => {
86
- return {
87
- url: dataset.url,
88
- path: "X",
89
- s: [null, v.matrix_index]
90
- };
91
- }));
92
- const [obsParams, setObsParams] = (0, _react.useState)({
93
- url: dataset.url,
94
- path: "obs/" + dataset.selectedObs?.name + (dataset.selectedObs?.type === _constants.OBS_TYPES.CATEGORICAL ? "/codes" : "")
95
- });
96
- const [labelObsParams, setLabelObsParams] = (0, _react.useState)([]);
97
- const obsmData = (0, _zarrHelper.useZarr)(obsmParams, null, _zarrHelper.GET_OPTIONS);
98
- const xData = (0, _zarrHelper.useMultipleZarr)(xParams, _zarrHelper.GET_OPTIONS, meanData);
99
- const obsData = (0, _zarrHelper.useZarr)(obsParams, null, _zarrHelper.GET_OPTIONS);
100
- const labelObsData = (0, _zarrHelper.useMultipleZarr)(labelObsParams, _zarrHelper.GET_OPTIONS);
101
- (0, _react.useEffect)(() => {
102
- setObsmParams(p => {
103
- return {
104
- ...p,
105
- path: "obsm/" + dataset.selectedObsm
106
- };
107
- });
108
- }, [dataset.selectedObsm]);
109
- (0, _react.useEffect)(() => {
110
- setXParams(!dataset.selectedVar ? [] : !dataset.selectedVar?.isSet ? [{
111
- url: dataset.url,
112
- path: "X",
113
- s: [null, dataset.selectedVar?.matrix_index]
114
- }] : _lodash.default.map(dataset.selectedVar?.vars, v => {
115
- return {
116
- url: dataset.url,
117
- path: "X",
118
- s: [null, v.matrix_index]
119
- };
120
- }));
121
- }, [dataset.selectedVar, dataset.url]);
122
- (0, _react.useEffect)(() => {
123
- setObsParams(p => {
124
- return {
125
- ...p,
126
- path: "obs/" + dataset.selectedObs?.name + (dataset.selectedObs?.type === _constants.OBS_TYPES.CATEGORICAL ? "/codes" : "")
127
- };
128
- });
129
- }, [dataset.selectedObs]);
130
- (0, _react.useEffect)(() => {
131
- setLabelObsParams(_lodash.default.map(dataset.labelObs, obs => {
132
- return {
133
- url: dataset.url,
134
- path: "obs/" + obs.name + (obs.type === _constants.OBS_TYPES.CATEGORICAL ? "/codes" : ""),
135
- key: obs.name
136
- };
137
- }));
138
- }, [dataset.labelObs, dataset.url]);
139
- (0, _react.useEffect)(() => {
140
- setObsmParams(p => {
141
- return {
142
- ...p,
143
- url: dataset.url
144
- };
145
- });
146
- setObsParams(p => {
147
- return {
148
- ...p,
149
- url: dataset.url
150
- };
151
- });
152
- }, [dataset.url]);
153
-
69
+ const obsmData = (0, _zarrData.useObsmData)();
70
+ const xData = (0, _zarrData.useXData)();
71
+ const obsData = (0, _zarrData.useObsData)();
72
+ const labelObsData = (0, _zarrData.useLabelObsData)();
154
73
  // @TODO: assert length of obsmData, xData, obsData is equal
155
74
 
156
75
  (0, _react.useEffect)(() => {
@@ -299,6 +218,8 @@ function Scatterplot(_ref) {
299
218
  }
300
219
  return inSlice;
301
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 ?
302
223
  const {
303
224
  filteredIndices,
304
225
  valueMin,
@@ -379,8 +300,21 @@ function Scatterplot(_ref) {
379
300
  index
380
301
  } = _ref2;
381
302
  const grayOut = filteredIndices && !filteredIndices.has(index);
382
- return getColor((data.values[index] - min) / (max - min), isCategorical, grayOut);
303
+ return getColor({
304
+ value: (data.values[index] - min) / (max - min),
305
+ categorical: isCategorical,
306
+ grayOut: grayOut
307
+ });
383
308
  }, [data.values, filteredIndices, getColor, isCategorical, max, min]);
309
+
310
+ // @TODO: add support for pseudospatial hover to reflect in radius
311
+ const getRadius = (0, _react.useCallback)((_d, _ref3) => {
312
+ let {
313
+ index
314
+ } = _ref3;
315
+ const grayOut = filteredIndices && !filteredIndices.has(index);
316
+ return grayOut ? 1 : 3;
317
+ }, [filteredIndices]);
384
318
  const memoizedLayers = (0, _react.useMemo)(() => {
385
319
  return [new _layers.ScatterplotLayer({
386
320
  id: "cherita-layer-scatterplot",
@@ -390,21 +324,22 @@ function Scatterplot(_ref) {
390
324
  radiusMinPixels: 1,
391
325
  getPosition: d => d,
392
326
  getFillColor: getFillColor,
393
- getRadius: 1,
327
+ getRadius: getRadius,
394
328
  updateTriggers: {
395
- getFillColor: getFillColor
329
+ getFillColor: getFillColor,
330
+ getRadius: getRadius
396
331
  }
397
332
  }), new _layers2.EditableGeoJsonLayer({
398
333
  id: "cherita-layer-draw",
399
334
  data: features,
400
335
  mode: mode,
401
336
  selectedFeatureIndexes,
402
- onEdit: _ref3 => {
337
+ onEdit: _ref4 => {
403
338
  let {
404
339
  updatedData,
405
340
  editType,
406
341
  editContext
407
- } = _ref3;
342
+ } = _ref4;
408
343
  setFeatures(updatedData);
409
344
  let updatedSelectedFeatureIndexes = selectedFeatureIndexes;
410
345
  if (editType === "addFeature") {
@@ -428,7 +363,7 @@ function Scatterplot(_ref) {
428
363
  }
429
364
  }
430
365
  })];
431
- }, [data.positions, features, getFillColor, mode, radius, selectedFeatureIndexes]);
366
+ }, [data.positions, features, getFillColor, getRadius, mode, radius, selectedFeatureIndexes]);
432
367
  const layers = (0, _react.useDeferredValue)(mode === _editModes.ViewMode ? memoizedLayers.reverse() : memoizedLayers); // draw scatterplot on top of polygons when in ViewMode
433
368
 
434
369
  (0, _react.useEffect)(() => {
@@ -453,11 +388,11 @@ function Scatterplot(_ref) {
453
388
  return `${o.name}: ${o.codesMap[v]}`;
454
389
  }
455
390
  };
456
- const getTooltip = _ref4 => {
391
+ const getTooltip = _ref5 => {
457
392
  let {
458
393
  object,
459
394
  index
460
- } = _ref4;
395
+ } = _ref5;
461
396
  if (!object) return;
462
397
  const text = [];
463
398
  if (dataset.colorEncoding === _constants.COLOR_ENCODINGS.OBS && dataset.selectedObs && !_lodash.default.some(dataset.labelObs, {
@@ -475,70 +410,82 @@ function Scatterplot(_ref) {
475
410
  }));
476
411
  }
477
412
  if (!text.length) return;
413
+ const grayOut = filteredIndices && !filteredIndices.has(index);
478
414
  return {
479
- text: text.length ? _lodash.default.compact(text).join("\n") : null
415
+ text: text.length ? _lodash.default.compact(text).join("\n") : null,
416
+ className: grayOut ? "tooltip-grayout" : "deck-tooltip",
417
+ style: !grayOut ? {
418
+ "border-left": `3px solid ${(0, _colorHelper.rgbToHex)(getFillColor(null, {
419
+ index
420
+ }))}`
421
+ } : {
422
+ "border-left": "none"
423
+ }
480
424
  };
481
425
  };
482
426
  const isPending = (isRendering || xData.isPending || obsmData.isPending) && !obsmData.isPending;
483
427
  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;
484
- return /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
485
- className: "cherita-scatterplot",
486
- children: [obsmData.isPending && /*#__PURE__*/(0, _jsxRuntime.jsx)(_LoadingIndicators.LoadingSpinner, {
487
- disableShrink: true
488
- }), isPending && /*#__PURE__*/(0, _jsxRuntime.jsx)(_LoadingIndicators.LoadingLinear, {}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_react2.DeckGL, {
489
- viewState: viewState,
490
- onViewStateChange: e => setViewState(e.viewState),
491
- controller: {
492
- doubleClickZoom: mode === _editModes.ViewMode
493
- },
494
- layers: layers,
495
- onClick: onLayerClick,
496
- getTooltip: getTooltip,
497
- onAfterRender: () => {
498
- setIsRendering(false);
499
- },
500
- useDevicePixels: false,
501
- getCursor: _ref5 => {
502
- let {
503
- isDragging
504
- } = _ref5;
505
- return mode !== _editModes.ViewMode ? "crosshair" : isDragging ? "grabbing" : "grab";
506
- },
507
- ref: deckRef
508
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_SpatialControls.SpatialControls, {
509
- mode: mode,
510
- setMode: setMode,
511
- features: features,
512
- setFeatures: setFeatures,
513
- selectedFeatureIndexes: selectedFeatureIndexes,
514
- resetBounds: () => setViewState(getBounds()),
515
- increaseZoom: () => setViewState(v => ({
516
- ...v,
517
- zoom: v.zoom + 1
518
- })),
519
- decreaseZoom: () => setViewState(v => ({
520
- ...v,
521
- zoom: v.zoom - 1
522
- }))
523
- }), /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
524
- className: "cherita-spatial-footer",
525
- children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
526
- className: "cherita-toolbox-footer",
527
- children: [error && !isPending && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactBootstrap.Alert, {
528
- variant: "danger",
529
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactFontawesome.FontAwesomeIcon, {
530
- icon: _freeSolidSvgIcons.faTriangleExclamation
531
- }), "\xA0Error loading data"]
532
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_Toolbox.Toolbox, {
533
- mode: dataset.colorEncoding === _constants.COLOR_ENCODINGS.VAR ? dataset.selectedVar.name : dataset.colorEncoding === _constants.COLOR_ENCODINGS.OBS ? dataset.selectedObs.name : null,
534
- obsLength: parseInt(obsmData.data?.length),
535
- slicedLength: parseInt(slicedLength)
428
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
429
+ className: "cherita-container-scatterplot",
430
+ children: /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
431
+ className: "cherita-scatterplot",
432
+ children: [obsmData.isPending && /*#__PURE__*/(0, _jsxRuntime.jsx)(_LoadingIndicators.LoadingSpinner, {
433
+ disableShrink: true
434
+ }), isPending && /*#__PURE__*/(0, _jsxRuntime.jsx)(_LoadingIndicators.LoadingLinear, {}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_react2.DeckGL, {
435
+ viewState: viewState,
436
+ onViewStateChange: e => setViewState(e.viewState),
437
+ controller: {
438
+ doubleClickZoom: mode === _editModes.ViewMode
439
+ },
440
+ layers: layers,
441
+ onClick: onLayerClick,
442
+ getTooltip: getTooltip,
443
+ onAfterRender: () => {
444
+ setIsRendering(false);
445
+ },
446
+ useDevicePixels: false,
447
+ getCursor: _ref6 => {
448
+ let {
449
+ isDragging
450
+ } = _ref6;
451
+ return mode !== _editModes.ViewMode ? "crosshair" : isDragging ? "grabbing" : "grab";
452
+ },
453
+ ref: deckRef
454
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_SpatialControls.SpatialControls, {
455
+ mode: mode,
456
+ setMode: setMode,
457
+ features: features,
458
+ setFeatures: setFeatures,
459
+ selectedFeatureIndexes: selectedFeatureIndexes,
460
+ resetBounds: () => setViewState(getBounds()),
461
+ increaseZoom: () => setViewState(v => ({
462
+ ...v,
463
+ zoom: v.zoom + 1
464
+ })),
465
+ decreaseZoom: () => setViewState(v => ({
466
+ ...v,
467
+ zoom: v.zoom - 1
468
+ }))
469
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
470
+ className: "cherita-spatial-footer",
471
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
472
+ className: "cherita-toolbox-footer",
473
+ children: [error && !isPending && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactBootstrap.Alert, {
474
+ variant: "danger",
475
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactFontawesome.FontAwesomeIcon, {
476
+ icon: _freeSolidSvgIcons.faTriangleExclamation
477
+ }), "\xA0Error loading data"]
478
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_Toolbox.Toolbox, {
479
+ mode: dataset.colorEncoding === _constants.COLOR_ENCODINGS.VAR ? dataset.selectedVar.name : dataset.colorEncoding === _constants.COLOR_ENCODINGS.OBS ? dataset.selectedObs.name : null,
480
+ obsLength: parseInt(obsmData.data?.length),
481
+ slicedLength: parseInt(slicedLength)
482
+ })]
483
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_Legend.Legend, {
484
+ isCategorical: isCategorical,
485
+ min: min,
486
+ max: max
536
487
  })]
537
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_Legend.Legend, {
538
- isCategorical: isCategorical,
539
- min: min,
540
- max: max
541
488
  })]
542
- })]
489
+ })
543
490
  });
544
491
  }
@@ -34,14 +34,14 @@ function VarHistogram(_ref) {
34
34
  const isSliced = dataset.sliceBy.obs || dataset.sliceBy.polygons;
35
35
  const [params, setParams] = (0, _react.useState)({
36
36
  url: dataset.url,
37
- var_index: item.matrix_index,
38
- obs_indices: isSliced && Array.from(filteredData.obsIndices || [])
37
+ varKey: item.matrix_index,
38
+ obsIndices: isSliced && Array.from(filteredData.obsIndices || [])
39
39
  });
40
40
  (0, _react.useEffect)(() => {
41
41
  setParams(p => {
42
42
  return {
43
43
  ...p,
44
- obs_indices: isSliced && Array.from(filteredData.obsIndices || [])
44
+ obsIndices: isSliced && Array.from(filteredData.obsIndices || [])
45
45
  };
46
46
  });
47
47
  }, [filteredData.obsIndices, isSliced]);
@@ -88,10 +88,22 @@ function VarHistogram(_ref) {
88
88
  });
89
89
  }
90
90
  function VarDiseaseInfoItem(item) {
91
+ const dispatch = (0, _DatasetContext.useDatasetDispatch)();
91
92
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.ListGroup.Item, {
92
93
  className: "feature-disease-info",
93
94
  children: /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
94
- children: [item.disease_name, " ", /*#__PURE__*/(0, _jsxRuntime.jsx)("br", {}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Table, {
95
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("button", {
96
+ type: "button",
97
+ className: "btn btn-link",
98
+ onClick: () => {
99
+ dispatch({
100
+ type: "select.disease",
101
+ id: item.disease_id,
102
+ name: item.disease_name
103
+ });
104
+ },
105
+ children: item.disease_name
106
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)("br", {}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Table, {
95
107
  striped: true,
96
108
  children: /*#__PURE__*/(0, _jsxRuntime.jsxs)("tbody", {
97
109
  children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)("tr", {
@@ -120,7 +132,7 @@ function VarDiseaseInfoItem(item) {
120
132
  })
121
133
  })]
122
134
  })
123
- });
135
+ }, item.disease_name);
124
136
  }
125
137
  function VarDiseaseInfo(_ref3) {
126
138
  let {
@@ -131,8 +143,8 @@ function VarDiseaseInfo(_ref3) {
131
143
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_VirtualizedList.VirtualizedList, {
132
144
  getDataAtIndex: index => data[index],
133
145
  count: data.length,
134
- estimateSize: 70,
135
- maxHeight: "40vh",
146
+ estimateSize: 140,
147
+ maxHeight: "100%",
136
148
  ItemComponent: VarDiseaseInfoItem
137
149
  })
138
150
  })
@@ -207,7 +219,7 @@ function SingleSelectionItem(_ref4) {
207
219
  }), hasDiseaseInfo && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Collapse, {
208
220
  in: openInfo,
209
221
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
210
- className: "mt-2",
222
+ className: "mt-2 var-disease-info-collapse",
211
223
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(VarDiseaseInfo, {
212
224
  data: fetchedData
213
225
  })
@@ -9,14 +9,47 @@ var _iconsMaterial = require("@mui/icons-material");
9
9
  var _lodash = _interopRequireDefault(require("lodash"));
10
10
  var _reactBootstrap = require("react-bootstrap");
11
11
  var _VarItem = require("./VarItem");
12
+ var _VarListToolbar = require("./VarListToolbar");
12
13
  var _VarSet = require("./VarSet");
13
14
  var _constants = require("../../constants/constants");
14
15
  var _DatasetContext = require("../../context/DatasetContext");
16
+ var _LoadingIndicators = require("../../utils/LoadingIndicators");
15
17
  var _requests = require("../../utils/requests");
16
18
  var _jsxRuntime = require("react/jsx-runtime");
17
19
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
18
20
  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); }
19
21
  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; }
22
+ // @TODO: optimize
23
+ const useVarMean = function (varKeys) {
24
+ let enabled = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
25
+ const ENDPOINT = "matrix/mean";
26
+ const dataset = (0, _DatasetContext.useDataset)();
27
+ const [params, setParams] = (0, _react.useState)({
28
+ url: dataset.url,
29
+ varKeys: _lodash.default.map(varKeys, v => v.isSet ? {
30
+ name: v.name,
31
+ indices: v.vars.map(v => v.index)
32
+ } : v.index),
33
+ varNamesCol: dataset.varNamesCol
34
+ });
35
+ (0, _react.useEffect)(() => {
36
+ setParams(p => {
37
+ return {
38
+ ...p,
39
+ varKeys: _lodash.default.map(varKeys, v => v.isSet ? {
40
+ name: v.name,
41
+ indices: v.vars.map(v => v.index)
42
+ } : v.index)
43
+ };
44
+ });
45
+ }, [varKeys]);
46
+ return (0, _requests.useFetch)(ENDPOINT, params, {
47
+ enabled: enabled
48
+ });
49
+ };
50
+
51
+ // @TODO: display where disease data comes from
52
+ // add to disease dataset metadata
20
53
  function DiseaseVarList(_ref) {
21
54
  let {
22
55
  makeListItem
@@ -25,6 +58,7 @@ function DiseaseVarList(_ref) {
25
58
  const dataset = (0, _DatasetContext.useDataset)();
26
59
  const dispatch = (0, _DatasetContext.useDatasetDispatch)();
27
60
  const [diseaseVars, setDiseaseVars] = (0, _react.useState)([]);
61
+ const [sortedDiseaseVars, setSortedDiseaseVars] = (0, _react.useState)([]);
28
62
  const [params, setParams] = (0, _react.useState)({
29
63
  url: dataset.url,
30
64
  col: dataset.varNamesCol,
@@ -39,25 +73,43 @@ function DiseaseVarList(_ref) {
39
73
  };
40
74
  });
41
75
  }, [dataset.selectedDisease]);
42
- const {
43
- fetchedData,
44
- isPending,
45
- serverError
46
- } = (0, _requests.useFetch)(ENDPOINT, params, {
76
+ const diseaseData = (0, _requests.useFetch)(ENDPOINT, params, {
47
77
  enabled: !!params.diseaseId
48
78
  });
49
79
  (0, _react.useEffect)(() => {
50
- if (!isPending && !serverError) {
51
- setDiseaseVars(fetchedData);
80
+ if (!diseaseData.isPending && !diseaseData.serverError) {
81
+ setDiseaseVars(diseaseData.fetchedData);
82
+ }
83
+ }, [diseaseData.fetchedData, diseaseData.isPending, diseaseData.serverError]);
84
+ const varMeans = useVarMean(diseaseVars, diseaseVars && dataset.varSort.disease.sort === _constants.VAR_SORT.MATRIX);
85
+ (0, _react.useEffect)(() => {
86
+ if (dataset.varSort.disease.sort === _constants.VAR_SORT.MATRIX) {
87
+ if (!varMeans.isPending && !varMeans.serverError) {
88
+ setSortedDiseaseVars(_lodash.default.orderBy(diseaseVars, o => {
89
+ return varMeans.fetchedData[o.name];
90
+ }, dataset.varSort.disease.sortOrder));
91
+ }
92
+ } else if (dataset.varSort.disease.sort === _constants.VAR_SORT.NAME) {
93
+ setSortedDiseaseVars(_lodash.default.orderBy(diseaseVars, "name", dataset.varSort.disease.sortOrder));
94
+ } else {
95
+ setSortedDiseaseVars(diseaseVars);
52
96
  }
53
- }, [fetchedData, isPending, serverError]);
54
- const diseaseVarList = _lodash.default.map(diseaseVars, item => {
97
+ }, [dataset.varSort.disease.sort, dataset.varSort.disease.sortOrder, diseaseVars, varMeans.fetchedData, varMeans.isPending, varMeans.serverError]);
98
+ const diseaseVarList = _lodash.default.map(sortedDiseaseVars, item => {
55
99
  return makeListItem(item, true);
56
100
  });
101
+ const isPending = diseaseData.isPending || varMeans.isPending && dataset.varSort.disease.sort === _constants.VAR_SORT.MATRIX;
57
102
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(_jsxRuntime.Fragment, {
58
- children: dataset.selectedDisease && (!diseaseVars.length ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Alert, {
59
- variant: "light",
60
- children: "No disease genes found."
103
+ children: dataset.selectedDisease && (!isPending && !diseaseVars?.length ? /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
104
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
105
+ className: "d-flex justify-content-between mt-3",
106
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)("h5", {
107
+ children: "Disease genes"
108
+ })
109
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Alert, {
110
+ variant: "light",
111
+ children: "No disease genes found."
112
+ })]
61
113
  }) : /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
62
114
  children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
63
115
  className: "d-flex justify-content-between mt-3",
@@ -74,8 +126,13 @@ function DiseaseVarList(_ref) {
74
126
  })]
75
127
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)("p", {
76
128
  children: dataset.selectedDisease?.name
77
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.ListGroup, {
78
- children: diseaseVarList
129
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_VarListToolbar.VarListToolbar, {
130
+ varType: "disease"
131
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
132
+ className: "position-relative",
133
+ children: [isPending && /*#__PURE__*/(0, _jsxRuntime.jsx)(_LoadingIndicators.LoadingSpinner, {}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.ListGroup, {
134
+ children: diseaseVarList
135
+ })]
79
136
  })]
80
137
  }))
81
138
  });
@@ -90,6 +147,7 @@ function VarNamesList(_ref2) {
90
147
  const dispatch = (0, _DatasetContext.useDatasetDispatch)();
91
148
  const [varButtons, setVarButtons] = (0, _react.useState)(mode === _constants.SELECTION_MODES.SINGLE ? dataset.selectedVar ? _lodash.default.unionWith([dataset.selectedVar], dataset.varSets, _lodash.default.isEqual) : [...dataset.varSets] : [...dataset.selectedMultiVar, ...dataset.varSets]);
92
149
  const [active, setActive] = (0, _react.useState)(mode === _constants.SELECTION_MODES.SINGLE ? dataset.selectedVar?.matrix_index || dataset.selectedVar?.name : dataset.selectedMultiVar.map(i => i.matrix_index || i.name));
150
+ const [sortedVarButtons, setSortedVarButtons] = (0, _react.useState)([]);
93
151
  (0, _react.useEffect)(() => {
94
152
  if (mode === _constants.SELECTION_MODES.SINGLE) {
95
153
  setVarButtons(v => {
@@ -139,6 +197,22 @@ function VarNamesList(_ref2) {
139
197
  });
140
198
  }
141
199
  }, [mode, dataset.varSets, dataset.selectedVar?.isSet, dataset.selectedVar?.name, dispatch]);
200
+ const varMeans = useVarMean(varButtons, dataset.varSort.var.sort === _constants.VAR_SORT.MATRIX);
201
+
202
+ // @TODO: deferr sortedVarButtons ?
203
+ (0, _react.useEffect)(() => {
204
+ if (dataset.varSort.var.sort === _constants.VAR_SORT.MATRIX) {
205
+ if (!varMeans.isPending && !varMeans.serverError) {
206
+ setSortedVarButtons(_lodash.default.orderBy(varButtons, o => {
207
+ return varMeans.fetchedData[o.name];
208
+ }, dataset.varSort.var.sortOrder));
209
+ }
210
+ } else if (dataset.varSort.var.sort === _constants.VAR_SORT.NAME) {
211
+ setSortedVarButtons(_lodash.default.orderBy(varButtons, "name", dataset.varSort.var.sortOrder));
212
+ } else {
213
+ setSortedVarButtons(varButtons);
214
+ }
215
+ }, [dataset.varSort.var.sort, dataset.varSort.var.sortOrder, varButtons, varMeans.isPending, varMeans.serverError, varMeans.fetchedData]);
142
216
  const makeListItem = function (item) {
143
217
  let isDiseaseGene = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
144
218
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.ListGroup.Item, {
@@ -160,7 +234,7 @@ function VarNamesList(_ref2) {
160
234
  })
161
235
  }, set.name);
162
236
  };
163
- const varList = _lodash.default.map(varButtons, item => {
237
+ const varList = _lodash.default.map(sortedVarButtons, item => {
164
238
  if (item.isSet) {
165
239
  return makeSetListItem(item);
166
240
  } else {
@@ -179,6 +253,7 @@ function VarNamesList(_ref2) {
179
253
  }
180
254
  return setName;
181
255
  };
256
+ const isPending = varMeans.isPending && dataset.varSort.var.sort === _constants.VAR_SORT.MATRIX;
182
257
  return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
183
258
  className: "position-relative",
184
259
  children: /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
@@ -216,13 +291,22 @@ function VarNamesList(_ref2) {
216
291
  children: "clear"
217
292
  })]
218
293
  })]
219
- }), !varList.length ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Alert, {
220
- variant: "light",
221
- children: "Search for a feature."
222
- }) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.ListGroup, {
223
- children: varList
224
- }), showDiseaseVarList && /*#__PURE__*/(0, _jsxRuntime.jsx)(DiseaseVarList, {
225
- makeListItem: makeListItem
294
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_jsxRuntime.Fragment, {
295
+ children: !varList.length ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Alert, {
296
+ variant: "light",
297
+ children: "Search for a feature."
298
+ }) : /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
299
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_VarListToolbar.VarListToolbar, {}), /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
300
+ className: "position-relative",
301
+ children: [isPending && /*#__PURE__*/(0, _jsxRuntime.jsx)(_LoadingIndicators.LoadingSpinner, {}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.ListGroup, {
302
+ children: varList
303
+ })]
304
+ })]
305
+ })
306
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_jsxRuntime.Fragment, {
307
+ children: showDiseaseVarList && /*#__PURE__*/(0, _jsxRuntime.jsx)(DiseaseVarList, {
308
+ makeListItem: makeListItem
309
+ })
226
310
  })]
227
311
  })
228
312
  });