@haniffalab/cherita-react 2.0.0 → 2.1.0
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/cjs/components/dotplot/Dotplot.js +4 -5
- package/dist/cjs/components/dotplot/DotplotControls.js +7 -3
- package/dist/cjs/components/heatmap/Heatmap.js +4 -5
- package/dist/cjs/components/icons/HeatmapIcon.js +2 -2
- package/dist/cjs/components/matrixplot/Matrixplot.js +4 -5
- package/dist/cjs/components/obs-list/ObsItem.js +7 -7
- package/dist/cjs/components/offcanvas/OffCanvas.js +7 -4
- package/dist/cjs/components/plot/PlotTypeSelector.js +49 -10
- package/dist/cjs/components/pseudospatial/Pseudospatial.js +8 -5
- package/dist/cjs/components/scatterplot/Scatterplot.js +134 -136
- package/dist/cjs/components/scatterplot/ScatterplotLayer.js +144 -0
- package/dist/cjs/components/scatterplot/SpatialControls.js +7 -4
- package/dist/cjs/components/scatterplot/Toolbox.js +8 -4
- package/dist/cjs/components/search-bar/SearchBar.js +51 -29
- package/dist/cjs/components/search-bar/SearchInfo.js +2 -2
- package/dist/cjs/components/search-bar/SearchResults.js +9 -6
- package/dist/cjs/components/toolbar/Toolbar.js +10 -65
- package/dist/cjs/components/var-list/VarItem.js +4 -6
- package/dist/cjs/components/var-list/VarList.js +17 -9
- package/dist/cjs/components/var-list/VarListToolbar.js +1 -1
- package/dist/cjs/components/var-list/VarSet.js +7 -5
- package/dist/cjs/components/violin/Violin.js +6 -7
- package/dist/cjs/constants/constants.js +6 -3
- package/dist/cjs/context/DatasetContext.js +11 -2
- package/dist/cjs/context/SettingsContext.js +27 -2
- package/dist/cjs/helpers/color-helper.js +17 -12
- package/dist/cjs/index.js +0 -7
- package/dist/cjs/utils/Legend.js +6 -5
- package/dist/cjs/utils/requests.js +2 -2
- package/dist/cjs/views/ObservationFeature/StandardView.js +1 -1
- package/dist/cjs/views/PerturbationMap/ObsExplorer.js +11 -9
- package/dist/cjs/views/PerturbationMap/StandardView.js +2 -1
- package/dist/cjs/workers/scatterplotData.js +16 -0
- package/dist/esm/components/dotplot/Dotplot.js +5 -6
- package/dist/esm/components/dotplot/DotplotControls.js +6 -3
- package/dist/esm/components/heatmap/Heatmap.js +5 -6
- package/dist/esm/components/icons/HeatmapIcon.js +2 -2
- package/dist/esm/components/matrixplot/Matrixplot.js +5 -6
- package/dist/esm/components/obs-list/ObsItem.js +7 -7
- package/dist/esm/components/offcanvas/OffCanvas.js +7 -4
- package/dist/esm/components/plot/PlotTypeSelector.js +49 -10
- package/dist/esm/components/pseudospatial/Pseudospatial.js +8 -5
- package/dist/esm/components/scatterplot/Scatterplot.js +132 -134
- package/dist/esm/components/scatterplot/ScatterplotLayer.js +137 -0
- package/dist/esm/components/scatterplot/SpatialControls.js +7 -4
- package/dist/esm/components/scatterplot/Toolbox.js +8 -4
- package/dist/esm/components/search-bar/SearchBar.js +52 -30
- package/dist/esm/components/search-bar/SearchInfo.js +2 -2
- package/dist/esm/components/search-bar/SearchResults.js +9 -6
- package/dist/esm/components/toolbar/Toolbar.js +9 -63
- package/dist/esm/components/var-list/VarItem.js +4 -6
- package/dist/esm/components/var-list/VarList.js +17 -9
- package/dist/esm/components/var-list/VarListToolbar.js +1 -1
- package/dist/esm/components/var-list/VarSet.js +7 -5
- package/dist/esm/components/violin/Violin.js +7 -8
- package/dist/esm/constants/constants.js +5 -2
- package/dist/esm/context/DatasetContext.js +11 -2
- package/dist/esm/context/SettingsContext.js +27 -2
- package/dist/esm/helpers/color-helper.js +17 -12
- package/dist/esm/index.js +0 -1
- package/dist/esm/utils/Legend.js +6 -5
- package/dist/esm/utils/requests.js +2 -2
- package/dist/esm/views/ObservationFeature/StandardView.js +1 -1
- package/dist/esm/views/PerturbationMap/ObsExplorer.js +11 -9
- package/dist/esm/views/PerturbationMap/StandardView.js +2 -1
- package/dist/esm/workers/scatterplotData.js +10 -0
- package/package.json +6 -3
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Button, ButtonGroup, OverlayTrigger, Tooltip } from 'react-bootstrap';
|
|
2
|
+
import { useDataset } from '../../context/DatasetContext';
|
|
2
3
|
import { formatNumerical } from '../../utils/string';
|
|
3
4
|
import { ObsmKeysList } from '../obsm-list/ObsmList';
|
|
4
5
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
@@ -9,6 +10,9 @@ export function Toolbox(_ref) {
|
|
|
9
10
|
slicedLength,
|
|
10
11
|
setHasObsm
|
|
11
12
|
} = _ref;
|
|
13
|
+
const {
|
|
14
|
+
obsLabel
|
|
15
|
+
} = useDataset();
|
|
12
16
|
return /*#__PURE__*/_jsx("div", {
|
|
13
17
|
className: "cherita-toolbox",
|
|
14
18
|
children: /*#__PURE__*/_jsxs(ButtonGroup, {
|
|
@@ -18,7 +22,7 @@ export function Toolbox(_ref) {
|
|
|
18
22
|
placement: "top",
|
|
19
23
|
overlay: /*#__PURE__*/_jsxs(Tooltip, {
|
|
20
24
|
id: "tooltip-dropped-mode",
|
|
21
|
-
children: ["You have selected ", formatNumerical(slicedLength), " out of", ' ', formatNumerical(obsLength), "
|
|
25
|
+
children: ["You have selected ", formatNumerical(slicedLength), " out of", ' ', formatNumerical(obsLength), " ", obsLabel.plural]
|
|
22
26
|
}),
|
|
23
27
|
children: /*#__PURE__*/_jsxs(Button, {
|
|
24
28
|
size: "sm",
|
|
@@ -27,13 +31,13 @@ export function Toolbox(_ref) {
|
|
|
27
31
|
cursor: 'default'
|
|
28
32
|
},
|
|
29
33
|
"aria-disabled": "true",
|
|
30
|
-
children: [formatNumerical(slicedLength), " of ", formatNumerical(obsLength), ' ',
|
|
34
|
+
children: [formatNumerical(slicedLength), " of ", formatNumerical(obsLength), ' ', obsLabel.plural]
|
|
31
35
|
})
|
|
32
36
|
}) : /*#__PURE__*/_jsx(OverlayTrigger, {
|
|
33
37
|
placement: "top",
|
|
34
38
|
overlay: /*#__PURE__*/_jsxs(Tooltip, {
|
|
35
39
|
id: "tooltip-dropped-mode",
|
|
36
|
-
children: ["You are viewing ", formatNumerical(obsLength), "
|
|
40
|
+
children: ["You are viewing ", formatNumerical(obsLength), " ", obsLabel.plural]
|
|
37
41
|
}),
|
|
38
42
|
children: /*#__PURE__*/_jsxs(Button, {
|
|
39
43
|
size: "sm",
|
|
@@ -42,7 +46,7 @@ export function Toolbox(_ref) {
|
|
|
42
46
|
cursor: 'default'
|
|
43
47
|
},
|
|
44
48
|
"aria-disabled": "true",
|
|
45
|
-
children: [formatNumerical(obsLength), "
|
|
49
|
+
children: [formatNumerical(obsLength), " ", obsLabel.plural]
|
|
46
50
|
})
|
|
47
51
|
}))]
|
|
48
52
|
})
|
|
@@ -3,7 +3,7 @@ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t =
|
|
|
3
3
|
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
|
|
4
4
|
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
|
|
5
5
|
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
6
|
-
import { useState } from 'react';
|
|
6
|
+
import { useState, useRef, useCallback, useMemo } from 'react';
|
|
7
7
|
import CloseIcon from '@mui/icons-material/Close';
|
|
8
8
|
import SearchIcon from '@mui/icons-material/Search';
|
|
9
9
|
import _ from 'lodash';
|
|
@@ -16,28 +16,41 @@ import Tab from 'react-bootstrap/Tab';
|
|
|
16
16
|
import { DiseaseInfo, VarInfo } from './SearchInfo';
|
|
17
17
|
import { DiseasesSearchResults, ObsSearchResults, VarSearchResults } from './SearchResults';
|
|
18
18
|
import { COLOR_ENCODINGS } from '../../constants/constants';
|
|
19
|
+
import { useDataset } from '../../context/DatasetContext';
|
|
19
20
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
21
|
+
function useVarSelect() {
|
|
22
|
+
const pendingVars = useRef(new Map());
|
|
23
|
+
const debouncedSelect = useMemo(() => _.debounce(dispatch => {
|
|
24
|
+
const vars = [...pendingVars.current.values()];
|
|
25
|
+
pendingVars.current.clear();
|
|
26
|
+
dispatch({
|
|
27
|
+
type: 'select.multivar.batch',
|
|
28
|
+
vars: vars
|
|
29
|
+
});
|
|
30
|
+
const lastItem = vars[vars.length - 1];
|
|
31
|
+
if (lastItem) {
|
|
32
|
+
dispatch({
|
|
33
|
+
type: 'select.var',
|
|
34
|
+
var: lastItem
|
|
35
|
+
});
|
|
36
|
+
dispatch({
|
|
37
|
+
type: 'set.colorEncoding',
|
|
38
|
+
value: COLOR_ENCODINGS.VAR
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
}, 500), []);
|
|
42
|
+
const onVarSelect = useCallback((dispatch, item) => {
|
|
43
|
+
dispatch({
|
|
44
|
+
type: 'add.var',
|
|
45
|
+
var: item
|
|
46
|
+
});
|
|
47
|
+
pendingVars.current.set(item.name, item);
|
|
48
|
+
debouncedSelect(dispatch);
|
|
49
|
+
}, [debouncedSelect]);
|
|
50
|
+
return {
|
|
51
|
+
onVarSelect,
|
|
52
|
+
debouncedSelect
|
|
53
|
+
};
|
|
41
54
|
}
|
|
42
55
|
function addVarSet(dispatch, _ref) {
|
|
43
56
|
let {
|
|
@@ -65,7 +78,7 @@ export function SearchModal(_ref2) {
|
|
|
65
78
|
text,
|
|
66
79
|
setText,
|
|
67
80
|
displayText,
|
|
68
|
-
|
|
81
|
+
handleVarSelect,
|
|
69
82
|
searchVar,
|
|
70
83
|
searchDiseases,
|
|
71
84
|
searchObs
|
|
@@ -85,6 +98,7 @@ export function SearchModal(_ref2) {
|
|
|
85
98
|
const [varResultsLength, setVarResultsLength] = useState(null);
|
|
86
99
|
const [diseaseResultsLength, setDiseaseResultsLength] = useState(null);
|
|
87
100
|
const [obsResultsLength, setObsResultsLength] = useState(null);
|
|
101
|
+
const dataset = useDataset();
|
|
88
102
|
return /*#__PURE__*/_jsxs(Modal, {
|
|
89
103
|
show: show,
|
|
90
104
|
onHide: handleClose,
|
|
@@ -160,7 +174,7 @@ export function SearchModal(_ref2) {
|
|
|
160
174
|
children: [searchVar && /*#__PURE__*/_jsx(Nav.Item, {
|
|
161
175
|
children: /*#__PURE__*/_jsxs(Nav.Link, {
|
|
162
176
|
eventKey: FEATURE_TYPE.VAR,
|
|
163
|
-
children: [
|
|
177
|
+
children: [_.capitalize(dataset.varLabel.plural), ' ', !!varResultsLength && "(".concat(varResultsLength, ")")]
|
|
164
178
|
})
|
|
165
179
|
}), searchDiseases && /*#__PURE__*/_jsx(Nav.Item, {
|
|
166
180
|
children: /*#__PURE__*/_jsxs(Nav.Link, {
|
|
@@ -170,7 +184,7 @@ export function SearchModal(_ref2) {
|
|
|
170
184
|
}), searchObs && /*#__PURE__*/_jsx(Nav.Item, {
|
|
171
185
|
children: /*#__PURE__*/_jsxs(Nav.Link, {
|
|
172
186
|
eventKey: FEATURE_TYPE.OBS,
|
|
173
|
-
children: [
|
|
187
|
+
children: [_.capitalize(dataset.obsLabel.plural), ' ', !!obsResultsLength && "(".concat(obsResultsLength, ")")]
|
|
174
188
|
})
|
|
175
189
|
})]
|
|
176
190
|
})
|
|
@@ -182,7 +196,7 @@ export function SearchModal(_ref2) {
|
|
|
182
196
|
eventKey: FEATURE_TYPE.VAR,
|
|
183
197
|
children: /*#__PURE__*/_jsx(VarSearchResults, {
|
|
184
198
|
text: text,
|
|
185
|
-
handleSelect:
|
|
199
|
+
handleSelect: handleVarSelect,
|
|
186
200
|
selectedResult: selectedResult.var,
|
|
187
201
|
setSelectedResult: item => setSelectedResult(prev => {
|
|
188
202
|
return _objectSpread(_objectSpread({}, prev), {}, {
|
|
@@ -207,7 +221,6 @@ export function SearchModal(_ref2) {
|
|
|
207
221
|
eventKey: FEATURE_TYPE.OBS,
|
|
208
222
|
children: /*#__PURE__*/_jsx(ObsSearchResults, {
|
|
209
223
|
text: text,
|
|
210
|
-
handleSelect: handleSelect,
|
|
211
224
|
selectedResult: selectedResult.obs,
|
|
212
225
|
setSelectedResult: item => setSelectedResult(prev => {
|
|
213
226
|
return _objectSpread(_objectSpread({}, prev), {}, {
|
|
@@ -230,7 +243,7 @@ export function SearchModal(_ref2) {
|
|
|
230
243
|
if (tab === FEATURE_TYPE.DISEASE) {
|
|
231
244
|
return /*#__PURE__*/_jsx(DiseaseInfo, {
|
|
232
245
|
disease: selectedResult.disease,
|
|
233
|
-
handleSelect:
|
|
246
|
+
handleSelect: handleVarSelect,
|
|
234
247
|
addVarSet: addVarSet
|
|
235
248
|
});
|
|
236
249
|
} else if (tab === FEATURE_TYPE.OBS) {
|
|
@@ -259,8 +272,13 @@ export function SearchBar(_ref3) {
|
|
|
259
272
|
searchObs = false
|
|
260
273
|
} = _ref3;
|
|
261
274
|
const [text, setText] = useState('');
|
|
262
|
-
const
|
|
275
|
+
const dataset = useDataset();
|
|
276
|
+
const displayText = [...(searchVar ? [dataset.varLabel.plural] : []), ...(searchDiseases ? ['diseases'] : []), ...(searchObs ? [dataset.obsLabel.plural] : [])].join(' and ');
|
|
263
277
|
const [showModal, setShowModal] = useState(false);
|
|
278
|
+
const {
|
|
279
|
+
onVarSelect,
|
|
280
|
+
debouncedSelect
|
|
281
|
+
} = useVarSelect();
|
|
264
282
|
return /*#__PURE__*/_jsxs("div", {
|
|
265
283
|
children: [/*#__PURE__*/_jsx(Form, {
|
|
266
284
|
onSubmit: e => {
|
|
@@ -286,7 +304,11 @@ export function SearchBar(_ref3) {
|
|
|
286
304
|
searchVar: searchVar,
|
|
287
305
|
searchDiseases: searchDiseases,
|
|
288
306
|
searchObs: searchObs,
|
|
289
|
-
|
|
307
|
+
handleVarSelect: onVarSelect,
|
|
308
|
+
handleClose: () => {
|
|
309
|
+
debouncedSelect.flush();
|
|
310
|
+
setShowModal(false);
|
|
311
|
+
}
|
|
290
312
|
})]
|
|
291
313
|
});
|
|
292
314
|
}
|
|
@@ -176,8 +176,8 @@ export function DiseaseInfo(_ref2) {
|
|
|
176
176
|
return /*#__PURE__*/_jsxs("div", {
|
|
177
177
|
children: [/*#__PURE__*/_jsx("h5", {
|
|
178
178
|
children: disease.disease_name
|
|
179
|
-
}), /*#__PURE__*/
|
|
180
|
-
children: "Implicated
|
|
179
|
+
}), /*#__PURE__*/_jsxs("h6", {
|
|
180
|
+
children: ["Implicated ", dataset.varLabel.plural]
|
|
181
181
|
}), isPending ? /*#__PURE__*/_jsx("p", {
|
|
182
182
|
children: "Loading..."
|
|
183
183
|
}) : /*#__PURE__*/_jsxs(_Fragment, {
|
|
@@ -8,6 +8,7 @@ import { faPlus } from '@fortawesome/free-solid-svg-icons';
|
|
|
8
8
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
|
9
9
|
import _ from 'lodash';
|
|
10
10
|
import { Button, ListGroup } from 'react-bootstrap';
|
|
11
|
+
import { useDataset } from '../../context/DatasetContext';
|
|
11
12
|
import { useSettingsDispatch } from '../../context/SettingsContext';
|
|
12
13
|
import { useDiseaseSearch, useObsSearch, useVarSearch } from '../../utils/search';
|
|
13
14
|
import { VirtualizedList } from '../../utils/VirtualizedList';
|
|
@@ -89,9 +90,10 @@ function SearchResultsBase(_ref) {
|
|
|
89
90
|
});
|
|
90
91
|
}
|
|
91
92
|
export function VarSearchResults(props) {
|
|
93
|
+
const dataset = useDataset();
|
|
92
94
|
return /*#__PURE__*/_jsx(SearchResultsBase, _objectSpread(_objectSpread({}, props), {}, {
|
|
93
95
|
searchHook: useVarSearch,
|
|
94
|
-
emptyLabel: "Search
|
|
96
|
+
emptyLabel: "Search for ".concat(dataset.varLabel.plural),
|
|
95
97
|
itemRenderer: _ref2 => {
|
|
96
98
|
var _item$index, _item$index2;
|
|
97
99
|
let {
|
|
@@ -129,17 +131,18 @@ export function VarSearchResults(props) {
|
|
|
129
131
|
}));
|
|
130
132
|
}
|
|
131
133
|
export function ObsSearchResults(props) {
|
|
134
|
+
const dataset = useDataset();
|
|
132
135
|
return /*#__PURE__*/_jsx(SearchResultsBase, _objectSpread(_objectSpread({}, props), {}, {
|
|
133
136
|
searchHook: useObsSearch,
|
|
134
|
-
emptyLabel: "Search
|
|
137
|
+
emptyLabel: "Search for ".concat(dataset.obsLabel.plural),
|
|
135
138
|
itemRenderer: _ref3 => {
|
|
136
139
|
let {
|
|
137
140
|
item,
|
|
138
141
|
dispatch,
|
|
139
|
-
handleClose,
|
|
140
142
|
selectedResult,
|
|
141
143
|
setSelectedResult,
|
|
142
|
-
isStale
|
|
144
|
+
isStale,
|
|
145
|
+
handleClose
|
|
143
146
|
} = _ref3;
|
|
144
147
|
const onObsSelect = (dispatch, item, closeModal) => {
|
|
145
148
|
dispatch({
|
|
@@ -163,7 +166,7 @@ export function ObsSearchResults(props) {
|
|
|
163
166
|
variant: "outline-secondary",
|
|
164
167
|
title: "Add to list",
|
|
165
168
|
disabled: isStale,
|
|
166
|
-
onClick: () => onObsSelect(dispatch, item,
|
|
169
|
+
onClick: () => onObsSelect(dispatch, item, handleClose),
|
|
167
170
|
children: /*#__PURE__*/_jsx(FontAwesomeIcon, {
|
|
168
171
|
icon: faPlus
|
|
169
172
|
})
|
|
@@ -177,7 +180,7 @@ export function ObsSearchResults(props) {
|
|
|
177
180
|
export function DiseasesSearchResults(props) {
|
|
178
181
|
return /*#__PURE__*/_jsx(SearchResultsBase, _objectSpread(_objectSpread({}, props), {}, {
|
|
179
182
|
searchHook: useDiseaseSearch,
|
|
180
|
-
emptyLabel: "Search diseases",
|
|
183
|
+
emptyLabel: "Search for diseases",
|
|
181
184
|
overscan: 250,
|
|
182
185
|
estimateSize: () => 32,
|
|
183
186
|
itemRenderer: _ref4 => {
|
|
@@ -1,75 +1,21 @@
|
|
|
1
1
|
import { faList, faSearch, faSliders } from '@fortawesome/free-solid-svg-icons';
|
|
2
2
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
|
3
|
+
import _ from 'lodash';
|
|
3
4
|
import { Container, Nav, Navbar, Button, ButtonGroup } from 'react-bootstrap';
|
|
5
|
+
import { useDataset } from '../../context/DatasetContext';
|
|
4
6
|
import usePlotVisibility from '../../utils/usePlotVisibility';
|
|
5
7
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
6
|
-
export const
|
|
7
|
-
let {
|
|
8
|
-
setShowCategories,
|
|
9
|
-
setShowSearch,
|
|
10
|
-
setShowControls,
|
|
11
|
-
Fullscreen
|
|
12
|
-
} = _ref;
|
|
13
|
-
const {
|
|
14
|
-
showCategoriesBtn,
|
|
15
|
-
showSearchBtn
|
|
16
|
-
} = usePlotVisibility(isFullscreen);
|
|
17
|
-
return /*#__PURE__*/_jsx(Navbar, {
|
|
18
|
-
expand: "md",
|
|
19
|
-
bg: "primary",
|
|
20
|
-
variant: "dark",
|
|
21
|
-
className: "cherita-navbar",
|
|
22
|
-
children: /*#__PURE__*/_jsxs(Container, {
|
|
23
|
-
fluid: true,
|
|
24
|
-
children: [/*#__PURE__*/_jsx(Navbar.Toggle, {
|
|
25
|
-
"aria-controls": "navbarScroll"
|
|
26
|
-
}), /*#__PURE__*/_jsx(Navbar.Collapse, {
|
|
27
|
-
id: "navbarScroll",
|
|
28
|
-
children: /*#__PURE__*/_jsxs(Nav, {
|
|
29
|
-
navbarScroll: true,
|
|
30
|
-
children: [showCategoriesBtn && /*#__PURE__*/_jsx(Nav.Item, {
|
|
31
|
-
className: "me-2",
|
|
32
|
-
children: /*#__PURE__*/_jsxs(Nav.Link, {
|
|
33
|
-
onClick: () => setShowCategories(true),
|
|
34
|
-
children: [/*#__PURE__*/_jsx(FontAwesomeIcon, {
|
|
35
|
-
icon: faList,
|
|
36
|
-
className: "me-2"
|
|
37
|
-
}), "Explore Categories"]
|
|
38
|
-
})
|
|
39
|
-
}), showSearchBtn && /*#__PURE__*/_jsx(Nav.Item, {
|
|
40
|
-
className: "me-2",
|
|
41
|
-
children: /*#__PURE__*/_jsxs(Nav.Link, {
|
|
42
|
-
onClick: () => setShowSearch(true),
|
|
43
|
-
children: [/*#__PURE__*/_jsx(FontAwesomeIcon, {
|
|
44
|
-
icon: faSearch,
|
|
45
|
-
className: "me-2"
|
|
46
|
-
}), "Search Genes"]
|
|
47
|
-
})
|
|
48
|
-
}), /*#__PURE__*/_jsx(Nav.Item, {
|
|
49
|
-
className: "me-2",
|
|
50
|
-
children: /*#__PURE__*/_jsxs(Nav.Link, {
|
|
51
|
-
onClick: () => setShowControls(true),
|
|
52
|
-
children: [/*#__PURE__*/_jsx(FontAwesomeIcon, {
|
|
53
|
-
icon: faSliders,
|
|
54
|
-
className: "me-2"
|
|
55
|
-
}), "Controls"]
|
|
56
|
-
})
|
|
57
|
-
}), ' ']
|
|
58
|
-
})
|
|
59
|
-
})]
|
|
60
|
-
})
|
|
61
|
-
});
|
|
62
|
-
};
|
|
63
|
-
export const PlotlyToolbar = _ref2 => {
|
|
8
|
+
export const PlotlyToolbar = _ref => {
|
|
64
9
|
let {
|
|
65
10
|
setShowCategories,
|
|
66
11
|
setShowSearch,
|
|
67
12
|
isFullscreen
|
|
68
|
-
} =
|
|
13
|
+
} = _ref;
|
|
69
14
|
const {
|
|
70
15
|
showCategoriesBtn,
|
|
71
16
|
showSearchBtn
|
|
72
17
|
} = usePlotVisibility(isFullscreen);
|
|
18
|
+
const dataset = useDataset();
|
|
73
19
|
return /*#__PURE__*/_jsxs(ButtonGroup, {
|
|
74
20
|
children: [showCategoriesBtn && /*#__PURE__*/_jsxs(Button, {
|
|
75
21
|
variant: "primary",
|
|
@@ -82,18 +28,18 @@ export const PlotlyToolbar = _ref2 => {
|
|
|
82
28
|
}), showSearchBtn && /*#__PURE__*/_jsxs(Button, {
|
|
83
29
|
variant: "primary",
|
|
84
30
|
onClick: () => setShowSearch(true),
|
|
85
|
-
title: "Search
|
|
31
|
+
title: "Search ".concat(dataset.varLabel.plural),
|
|
86
32
|
children: [/*#__PURE__*/_jsx(FontAwesomeIcon, {
|
|
87
33
|
icon: faSearch,
|
|
88
34
|
className: "me-1"
|
|
89
|
-
}),
|
|
35
|
+
}), _.capitalize(dataset.varLabel.plural)]
|
|
90
36
|
})]
|
|
91
37
|
});
|
|
92
38
|
};
|
|
93
|
-
export const PlotlyModebarControls =
|
|
39
|
+
export const PlotlyModebarControls = _ref2 => {
|
|
94
40
|
let {
|
|
95
41
|
onClick
|
|
96
|
-
} =
|
|
42
|
+
} = _ref2;
|
|
97
43
|
return {
|
|
98
44
|
name: 'Controls',
|
|
99
45
|
icon: {
|
|
@@ -147,7 +147,7 @@ export function SelectionItem(_ref3) {
|
|
|
147
147
|
className: "ms-auto d-flex align-items-center gap-1",
|
|
148
148
|
children: [hasDiseaseInfo && /*#__PURE__*/_jsx(MoreVert, {}), /*#__PURE__*/_jsx(VarHistogram, {
|
|
149
149
|
item: item
|
|
150
|
-
}), showSetColorEncoding && /*#__PURE__*/
|
|
150
|
+
}), showSetColorEncoding && /*#__PURE__*/_jsx(Button, {
|
|
151
151
|
type: "button",
|
|
152
152
|
variant: isActive ? 'primary' : isNotInData ? 'outline-secondary' : 'outline-primary',
|
|
153
153
|
className: "m-0 p-0 px-1",
|
|
@@ -157,11 +157,9 @@ export function SelectionItem(_ref3) {
|
|
|
157
157
|
},
|
|
158
158
|
disabled: isNotInData,
|
|
159
159
|
title: isNotInData ? 'Not present in data' : isMultiple ? isActive ? 'Remove from plot' : 'Add to plot' : 'Set as color encoding',
|
|
160
|
-
children:
|
|
161
|
-
icon: faDroplet
|
|
162
|
-
})
|
|
163
|
-
icon: faCheck
|
|
164
|
-
})]
|
|
160
|
+
children: /*#__PURE__*/_jsx(FontAwesomeIcon, {
|
|
161
|
+
icon: isMultiple ? faCheck : faDroplet
|
|
162
|
+
})
|
|
165
163
|
}, item.matrix_index), showRemove && /*#__PURE__*/_jsx(Button, {
|
|
166
164
|
type: "button",
|
|
167
165
|
className: "m-0 p-0 px-1",
|
|
@@ -58,25 +58,33 @@ export const sortMeans = (i, means) => {
|
|
|
58
58
|
return means[i.name] || _.min(_.values(means)) - 1;
|
|
59
59
|
};
|
|
60
60
|
export function VarNamesList(_ref) {
|
|
61
|
+
var _selectedVar$matrix_i;
|
|
61
62
|
let {
|
|
62
|
-
mode = SELECTION_MODES.SINGLE
|
|
63
|
-
displayName = 'genes'
|
|
63
|
+
mode = SELECTION_MODES.SINGLE
|
|
64
64
|
} = _ref;
|
|
65
65
|
const settings = useSettings();
|
|
66
66
|
const dispatch = useSettingsDispatch();
|
|
67
|
+
const dataset = useDataset();
|
|
67
68
|
const selectedVar = useSelectedVar();
|
|
68
69
|
const selectedMultiVar = useSelectedMultiVar();
|
|
69
70
|
const settingsVars = useSettingsVars();
|
|
70
|
-
const [active, setActive] = useState(mode === SELECTION_MODES.SINGLE ? (selectedVar === null || selectedVar === void 0 ? void 0 : selectedVar.matrix_index)
|
|
71
|
+
const [active, setActive] = useState(mode === SELECTION_MODES.SINGLE ? (_selectedVar$matrix_i = selectedVar === null || selectedVar === void 0 ? void 0 : selectedVar.matrix_index) !== null && _selectedVar$matrix_i !== void 0 ? _selectedVar$matrix_i : selectedVar === null || selectedVar === void 0 ? void 0 : selectedVar.name : selectedMultiVar.map(i => {
|
|
72
|
+
var _i$matrix_index;
|
|
73
|
+
return (_i$matrix_index = i.matrix_index) !== null && _i$matrix_index !== void 0 ? _i$matrix_index : i.name;
|
|
74
|
+
}));
|
|
71
75
|
const [sortedVars, setSortedVars] = useState([]);
|
|
72
76
|
useEffect(() => {
|
|
73
77
|
if (mode === SELECTION_MODES.SINGLE) {
|
|
74
|
-
|
|
78
|
+
var _selectedVar$matrix_i2;
|
|
79
|
+
setActive((_selectedVar$matrix_i2 = selectedVar === null || selectedVar === void 0 ? void 0 : selectedVar.matrix_index) !== null && _selectedVar$matrix_i2 !== void 0 ? _selectedVar$matrix_i2 : selectedVar === null || selectedVar === void 0 ? void 0 : selectedVar.name);
|
|
75
80
|
}
|
|
76
81
|
}, [mode, selectedVar]);
|
|
77
82
|
useEffect(() => {
|
|
78
83
|
if (mode === SELECTION_MODES.MULTIPLE) {
|
|
79
|
-
setActive(selectedMultiVar.map(i =>
|
|
84
|
+
setActive(selectedMultiVar.map(i => {
|
|
85
|
+
var _i$matrix_index2;
|
|
86
|
+
return (_i$matrix_index2 = i.matrix_index) !== null && _i$matrix_index2 !== void 0 ? _i$matrix_index2 : i.name;
|
|
87
|
+
}));
|
|
80
88
|
}
|
|
81
89
|
}, [mode, selectedMultiVar]);
|
|
82
90
|
const varMeans = useVarMean(settingsVars, settings.varSort.var.sort === VAR_SORT.MATRIX);
|
|
@@ -144,9 +152,9 @@ export function VarNamesList(_ref) {
|
|
|
144
152
|
children: [/*#__PURE__*/_jsxs("div", {
|
|
145
153
|
className: "d-flex justify-content-between mb-2",
|
|
146
154
|
children: [/*#__PURE__*/_jsx("h5", {
|
|
147
|
-
children: _.capitalize(
|
|
155
|
+
children: _.capitalize(dataset.varLabel.plural)
|
|
148
156
|
}), /*#__PURE__*/_jsxs(ButtonGroup, {
|
|
149
|
-
"aria-label": "
|
|
157
|
+
"aria-label": "Options",
|
|
150
158
|
size: "sm",
|
|
151
159
|
children: [/*#__PURE__*/_jsx(Button, {
|
|
152
160
|
variant: "info",
|
|
@@ -175,9 +183,9 @@ export function VarNamesList(_ref) {
|
|
|
175
183
|
})]
|
|
176
184
|
})]
|
|
177
185
|
}), /*#__PURE__*/_jsx(_Fragment, {
|
|
178
|
-
children: !varList.length ? /*#__PURE__*/
|
|
186
|
+
children: !varList.length ? /*#__PURE__*/_jsxs(Alert, {
|
|
179
187
|
variant: "light",
|
|
180
|
-
children: "Search for
|
|
188
|
+
children: ["Search for ", dataset.varLabel.plural]
|
|
181
189
|
}) : /*#__PURE__*/_jsxs(_Fragment, {
|
|
182
190
|
children: [/*#__PURE__*/_jsx(VarListToolbar, {}), /*#__PURE__*/_jsxs("div", {
|
|
183
191
|
className: "overflow-auto flex-grow-1 modern-scrollbars",
|
|
@@ -40,7 +40,7 @@ export function VarListToolbar(_ref) {
|
|
|
40
40
|
className: "d-flex justify-content-end align-items-center mb-2",
|
|
41
41
|
children: /*#__PURE__*/_jsxs(ToggleButtonGroup, {
|
|
42
42
|
name: "sortfeatures",
|
|
43
|
-
"aria-label": "Sort
|
|
43
|
+
"aria-label": "Sort by",
|
|
44
44
|
size: "sm",
|
|
45
45
|
type: "radio",
|
|
46
46
|
children: [/*#__PURE__*/_jsx(ToggleButton, {
|
|
@@ -5,6 +5,7 @@ import _ from 'lodash';
|
|
|
5
5
|
import { Button, Collapse, ListGroup, OverlayTrigger, Tooltip } from 'react-bootstrap';
|
|
6
6
|
import { SelectionItem } from './VarItem';
|
|
7
7
|
import { COLOR_ENCODINGS, SELECTION_MODES } from '../../constants/constants';
|
|
8
|
+
import { useDataset } from '../../context/DatasetContext';
|
|
8
9
|
import { useSettings, useSettingsDispatch } from '../../context/SettingsContext';
|
|
9
10
|
import { SearchModal } from '../search-bar/SearchBar';
|
|
10
11
|
|
|
@@ -26,6 +27,7 @@ function SelectionSet(_ref) {
|
|
|
26
27
|
removeSetVar,
|
|
27
28
|
isMultiple = false
|
|
28
29
|
} = _ref;
|
|
30
|
+
const dataset = useDataset();
|
|
29
31
|
const [openSet, setOpenSet] = useState(false);
|
|
30
32
|
const [showModal, setShowModal] = useState(false);
|
|
31
33
|
const [searchText, setSearchText] = useState('');
|
|
@@ -38,9 +40,9 @@ function SelectionSet(_ref) {
|
|
|
38
40
|
})
|
|
39
41
|
}, v.name);
|
|
40
42
|
}) : /*#__PURE__*/_jsx(ListGroup.Item, {
|
|
41
|
-
children: /*#__PURE__*/
|
|
43
|
+
children: /*#__PURE__*/_jsxs("div", {
|
|
42
44
|
className: "text-muted",
|
|
43
|
-
children: "No
|
|
45
|
+
children: ["No ", dataset.varLabel.plural, " in this set"]
|
|
44
46
|
})
|
|
45
47
|
});
|
|
46
48
|
return /*#__PURE__*/_jsxs(_Fragment, {
|
|
@@ -59,8 +61,8 @@ function SelectionSet(_ref) {
|
|
|
59
61
|
className: "d-flex align-items-center gap-1",
|
|
60
62
|
children: [/*#__PURE__*/_jsx(OverlayTrigger, {
|
|
61
63
|
placement: "top",
|
|
62
|
-
overlay: /*#__PURE__*/
|
|
63
|
-
children: "This set represents the mean value of its
|
|
64
|
+
overlay: /*#__PURE__*/_jsxs(Tooltip, {
|
|
65
|
+
children: ["This set represents the mean value of its", ' ', dataset.varLabel.plural]
|
|
64
66
|
}),
|
|
65
67
|
children: /*#__PURE__*/_jsx(FontAwesomeIcon, {
|
|
66
68
|
icon: faCircleInfo
|
|
@@ -131,7 +133,7 @@ function SelectionSet(_ref) {
|
|
|
131
133
|
handleClose: () => setShowModal(false),
|
|
132
134
|
text: searchText,
|
|
133
135
|
setText: setSearchText,
|
|
134
|
-
displayText:
|
|
136
|
+
displayText: dataset.varLabel.plural,
|
|
135
137
|
handleSelect: (d, i) => {
|
|
136
138
|
addVarToSet(d, set, i);
|
|
137
139
|
},
|
|
@@ -9,7 +9,7 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
|
|
9
9
|
import _ from 'lodash';
|
|
10
10
|
import { Badge, Button } from 'react-bootstrap';
|
|
11
11
|
import Plot from 'react-plotly.js';
|
|
12
|
-
import { PLOTLY_MODEBAR_BUTTONS, VIOLIN_MODES } from '../../constants/constants';
|
|
12
|
+
import { PLOT_TYPES, PLOTLY_MODEBAR_BUTTONS, VIOLIN_MODES } from '../../constants/constants';
|
|
13
13
|
import { useDataset } from '../../context/DatasetContext';
|
|
14
14
|
import { useFilteredData } from '../../context/FilterContext';
|
|
15
15
|
import { useSettings } from '../../context/SettingsContext';
|
|
@@ -27,7 +27,6 @@ export function Violin(_ref) {
|
|
|
27
27
|
setShowCategories,
|
|
28
28
|
setShowSearch,
|
|
29
29
|
setShowControls,
|
|
30
|
-
plotType,
|
|
31
30
|
setPlotType,
|
|
32
31
|
isFullscreen = false
|
|
33
32
|
} = _ref;
|
|
@@ -168,7 +167,7 @@ export function Violin(_ref) {
|
|
|
168
167
|
return /*#__PURE__*/_jsxs(PlotAlert, {
|
|
169
168
|
variant: "info",
|
|
170
169
|
heading: "Set up your violin plot",
|
|
171
|
-
plotType:
|
|
170
|
+
plotType: PLOT_TYPES.VIOLINPLOT,
|
|
172
171
|
setPlotType: setPlotType,
|
|
173
172
|
children: [mode === VIOLIN_MODES.MULTIKEY && /*#__PURE__*/_jsxs("p", {
|
|
174
173
|
className: "p-0 m-0",
|
|
@@ -176,8 +175,8 @@ export function Violin(_ref) {
|
|
|
176
175
|
variant: "link",
|
|
177
176
|
className: "border-0 p-0 align-baseline",
|
|
178
177
|
onClick: setShowSearch,
|
|
179
|
-
children:
|
|
180
|
-
}) :
|
|
178
|
+
children: dataset.varLabel.plural
|
|
179
|
+
}) : dataset.varLabel.plural, ' ', "to display their ", dataset.valueLabel, " distributions across all", ' ', dataset.obsLabel.plural, "."]
|
|
181
180
|
}), mode === VIOLIN_MODES.GROUPBY && /*#__PURE__*/_jsxs("p", {
|
|
182
181
|
className: "p-0 m-0",
|
|
183
182
|
children: ["Select a", ' ', showCategoriesBtn ? /*#__PURE__*/_jsx(Button, {
|
|
@@ -189,15 +188,15 @@ export function Violin(_ref) {
|
|
|
189
188
|
variant: "link",
|
|
190
189
|
className: "border-0 p-0 align-baseline",
|
|
191
190
|
onClick: setShowSearch,
|
|
192
|
-
children:
|
|
193
|
-
}) :
|
|
191
|
+
children: dataset.varLabel.singular
|
|
192
|
+
}) : dataset.varLabel.singular, ' ', "to view its distribution within each group."]
|
|
194
193
|
})]
|
|
195
194
|
});
|
|
196
195
|
} else {
|
|
197
196
|
return /*#__PURE__*/_jsx(PlotAlert, {
|
|
198
197
|
variant: "danger",
|
|
199
198
|
heading: "Error displaying the violin plot",
|
|
200
|
-
plotType:
|
|
199
|
+
plotType: PLOT_TYPES.VIOLINPLOT,
|
|
201
200
|
setPlotType: setPlotType,
|
|
202
201
|
children: serverError.message || 'An unexpected error occurred while generating the plot.'
|
|
203
202
|
});
|
|
@@ -93,11 +93,14 @@ export const PSEUDOSPATIAL_CATEGORICAL_MODES = {
|
|
|
93
93
|
// `default` cols to be shown out of accordion, at top of obslist
|
|
94
94
|
// default values from cellxgene schema
|
|
95
95
|
export const DEFAULT_OBS_GROUP = ['assay', 'cell_type', 'development_stage', 'disease', 'donor_id', 'organism', 'self_reported_ethnicity', 'sex', 'suspension_type', 'tissue', 'tissue_type'];
|
|
96
|
-
export const PLOTLY_MODEBAR_BUTTONS = ['toImage', 'zoom2d', 'pan2d', 'zoomIn2d', 'zoomOut2d', 'autoScale2d'
|
|
96
|
+
export const PLOTLY_MODEBAR_BUTTONS = ['toImage', 'zoom2d', 'pan2d', 'zoomIn2d', 'zoomOut2d', 'autoScale2d'];
|
|
97
97
|
export const BREAKPOINTS = {
|
|
98
98
|
LG: '(max-width: 991.98px)',
|
|
99
99
|
XL: '(max-width: 1199.98px)'
|
|
100
100
|
};
|
|
101
101
|
|
|
102
102
|
// In order of priority
|
|
103
|
-
export const DEFAULT_OBSM_KEYS = ['x_umap', 'x_tsne', 'x_scvi', 'x_pca'];
|
|
103
|
+
export const DEFAULT_OBSM_KEYS = ['x_umap', 'x_tsne', 'x_scvi', 'x_pca'];
|
|
104
|
+
export const GRAY = [214, 212, 212];
|
|
105
|
+
export const GRAY_MIX = 0.95;
|
|
106
|
+
export const GRAY_ALPHA = 0.75;
|
|
@@ -51,7 +51,7 @@ const persistOptions = {
|
|
|
51
51
|
return false;
|
|
52
52
|
}
|
|
53
53
|
},
|
|
54
|
-
buster: "2.
|
|
54
|
+
buster: "2.1.0" || '0.0.0'
|
|
55
55
|
// @TODO: add maxAge and api version numbers as buster
|
|
56
56
|
};
|
|
57
57
|
const initialDataset = {
|
|
@@ -72,7 +72,16 @@ const initialDataset = {
|
|
|
72
72
|
dataUrl: null,
|
|
73
73
|
// for additional data in a remote .parquet file
|
|
74
74
|
dataFilterCols: null // map of obs cols to filter data in .parquet file
|
|
75
|
-
}
|
|
75
|
+
},
|
|
76
|
+
obsLabel: {
|
|
77
|
+
singular: 'cell',
|
|
78
|
+
plural: 'cells'
|
|
79
|
+
},
|
|
80
|
+
varLabel: {
|
|
81
|
+
singular: 'gene',
|
|
82
|
+
plural: 'genes'
|
|
83
|
+
},
|
|
84
|
+
valueLabel: 'expression'
|
|
76
85
|
};
|
|
77
86
|
export function DatasetProvider(_ref2) {
|
|
78
87
|
let {
|