@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.
- package/dist/components/full-page/FullPage.js +50 -6
- package/dist/components/obs-list/ObsItem.js +11 -5
- package/dist/components/obs-list/ObsList.js +8 -2
- package/dist/components/pseudospatial/Pseudospatial.js +215 -0
- package/dist/components/pseudospatial/PseudospatialControls.js +12 -0
- package/dist/components/pseudospatial/PseudospatialToolbar.js +155 -0
- package/dist/components/scatterplot/Scatterplot.js +100 -153
- package/dist/components/var-list/VarItem.js +20 -8
- package/dist/components/var-list/VarList.js +106 -22
- package/dist/components/var-list/VarListToolbar.js +101 -0
- package/dist/components/var-list/VarSet.js +1 -0
- package/dist/constants/constants.js +26 -1
- package/dist/context/DatasetContext.js +90 -3
- package/dist/context/FilterContext.js +1 -0
- package/dist/css/cherita.css +39 -0
- package/dist/css/cherita.css.map +1 -1
- package/dist/helpers/color-helper.js +12 -8
- package/dist/helpers/zarr-helper.js +2 -0
- package/dist/index.js +19 -0
- package/dist/utils/ImageViewer.js +40 -0
- package/dist/{components/scatterplot → utils}/Legend.js +12 -7
- package/dist/utils/requests.js +8 -6
- package/dist/utils/string.js +3 -3
- package/dist/utils/zarrData.js +101 -0
- package/package.json +2 -2
- package/scss/cherita.scss +39 -0
|
@@ -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
|
|
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
|
|
78
|
-
|
|
79
|
-
|
|
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(
|
|
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:
|
|
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:
|
|
337
|
+
onEdit: _ref4 => {
|
|
403
338
|
let {
|
|
404
339
|
updatedData,
|
|
405
340
|
editType,
|
|
406
341
|
editContext
|
|
407
|
-
} =
|
|
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 =
|
|
391
|
+
const getTooltip = _ref5 => {
|
|
457
392
|
let {
|
|
458
393
|
object,
|
|
459
394
|
index
|
|
460
|
-
} =
|
|
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.
|
|
485
|
-
className: "cherita-scatterplot",
|
|
486
|
-
children:
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
className: "cherita-
|
|
527
|
-
children: [
|
|
528
|
-
|
|
529
|
-
children: [/*#__PURE__*/(0, _jsxRuntime.
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
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
|
-
|
|
38
|
-
|
|
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
|
-
|
|
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: [
|
|
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:
|
|
135
|
-
maxHeight: "
|
|
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(
|
|
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
|
|
59
|
-
|
|
60
|
-
|
|
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)(
|
|
78
|
-
|
|
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(
|
|
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
|
-
}),
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
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
|
});
|