@haniffalab/cherita-react 1.2.0 → 1.3.0-dev.2025-05-28.9afc380f
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/controls/Controls.js +60 -0
- package/dist/cjs/components/dotplot/Dotplot.js +47 -38
- package/dist/cjs/components/dotplot/DotplotControls.js +77 -114
- package/dist/cjs/components/full-page/FullPage.js +29 -33
- package/dist/cjs/components/full-page/FullPagePseudospatial.js +30 -33
- package/dist/cjs/components/heatmap/Heatmap.js +33 -22
- package/dist/cjs/components/heatmap/HeatmapControls.js +2 -19
- package/dist/cjs/components/matrixplot/Matrixplot.js +35 -24
- package/dist/cjs/components/matrixplot/MatrixplotControls.js +4 -34
- package/dist/cjs/components/obs-list/ObsItem.js +63 -51
- package/dist/cjs/components/obs-list/ObsList.js +53 -48
- package/dist/cjs/components/obsm-list/ObsmList.js +17 -12
- package/dist/cjs/components/offcanvas/index.js +14 -11
- package/dist/cjs/components/pseudospatial/Pseudospatial.js +78 -68
- package/dist/cjs/components/pseudospatial/PseudospatialToolbar.js +27 -21
- package/dist/cjs/components/scatterplot/Scatterplot.js +82 -76
- package/dist/cjs/components/scatterplot/ScatterplotControls.js +18 -31
- package/dist/cjs/components/scatterplot/SpatialControls.js +53 -23
- package/dist/cjs/components/scatterplot/Toolbox.js +1 -18
- package/dist/cjs/components/search-bar/SearchBar.js +156 -59
- package/dist/cjs/components/search-bar/SearchInfo.js +182 -0
- package/dist/cjs/components/search-bar/SearchResults.js +90 -60
- package/dist/cjs/components/var-list/VarItem.js +52 -75
- package/dist/cjs/components/var-list/VarList.js +47 -172
- package/dist/cjs/components/var-list/VarListToolbar.js +7 -8
- package/dist/cjs/components/var-list/VarSet.js +66 -57
- package/dist/cjs/components/violin/Violin.js +54 -43
- package/dist/cjs/components/violin/ViolinControls.js +4 -20
- package/dist/cjs/context/DatasetContext.js +26 -513
- package/dist/cjs/context/FilterContext.js +9 -8
- package/dist/cjs/context/SettingsContext.js +539 -0
- package/dist/cjs/context/ZarrDataContext.js +1 -2
- package/dist/cjs/helpers/color-helper.js +8 -8
- package/dist/cjs/helpers/zarr-helper.js +19 -16
- package/dist/cjs/utils/Filter.js +25 -21
- package/dist/cjs/utils/Histogram.js +4 -3
- package/dist/cjs/utils/ImageViewer.js +1 -2
- package/dist/cjs/utils/Legend.js +18 -12
- package/dist/cjs/utils/LoadingIndicators.js +1 -1
- package/dist/cjs/utils/VirtualizedList.js +16 -13
- package/dist/cjs/utils/errors.js +20 -22
- package/dist/cjs/utils/requests.js +13 -10
- package/dist/cjs/utils/zarrData.js +31 -50
- package/dist/css/cherita.css +84 -24
- package/dist/css/cherita.css.map +1 -1
- package/dist/esm/components/controls/Controls.js +51 -0
- package/dist/esm/components/dotplot/Dotplot.js +47 -37
- package/dist/esm/components/dotplot/DotplotControls.js +77 -112
- package/dist/esm/components/full-page/FullPage.js +29 -32
- package/dist/esm/components/full-page/FullPagePseudospatial.js +30 -32
- package/dist/esm/components/heatmap/Heatmap.js +32 -20
- package/dist/esm/components/heatmap/HeatmapControls.js +3 -20
- package/dist/esm/components/matrixplot/Matrixplot.js +34 -22
- package/dist/esm/components/matrixplot/MatrixplotControls.js +5 -35
- package/dist/esm/components/obs-list/ObsItem.js +63 -49
- package/dist/esm/components/obs-list/ObsList.js +53 -47
- package/dist/esm/components/obsm-list/ObsmList.js +17 -11
- package/dist/esm/components/offcanvas/index.js +14 -11
- package/dist/esm/components/pseudospatial/Pseudospatial.js +77 -66
- package/dist/esm/components/pseudospatial/PseudospatialToolbar.js +27 -20
- package/dist/esm/components/scatterplot/Scatterplot.js +81 -74
- package/dist/esm/components/scatterplot/ScatterplotControls.js +18 -29
- package/dist/esm/components/scatterplot/SpatialControls.js +54 -23
- package/dist/esm/components/scatterplot/Toolbox.js +1 -18
- package/dist/esm/components/search-bar/SearchBar.js +156 -59
- package/dist/esm/components/search-bar/SearchInfo.js +173 -0
- package/dist/esm/components/search-bar/SearchResults.js +91 -60
- package/dist/esm/components/var-list/VarItem.js +53 -76
- package/dist/esm/components/var-list/VarList.js +47 -171
- package/dist/esm/components/var-list/VarListToolbar.js +6 -6
- package/dist/esm/components/var-list/VarSet.js +67 -57
- package/dist/esm/components/violin/Violin.js +53 -41
- package/dist/esm/components/violin/ViolinControls.js +5 -21
- package/dist/esm/context/DatasetContext.js +25 -510
- package/dist/esm/context/FilterContext.js +8 -6
- package/dist/esm/context/SettingsContext.js +528 -0
- package/dist/esm/helpers/color-helper.js +8 -8
- package/dist/esm/helpers/zarr-helper.js +19 -16
- package/dist/esm/utils/Filter.js +25 -21
- package/dist/esm/utils/Histogram.js +4 -3
- package/dist/esm/utils/Legend.js +17 -10
- package/dist/esm/utils/LoadingIndicators.js +1 -1
- package/dist/esm/utils/VirtualizedList.js +15 -11
- package/dist/esm/utils/errors.js +20 -22
- package/dist/esm/utils/requests.js +13 -10
- package/dist/esm/utils/zarrData.js +33 -51
- package/package.json +6 -3
- package/scss/cherita.scss +50 -9
- package/scss/components/layouts.scss +24 -13
- package/scss/components/lists.scss +10 -0
- package/scss/components/plots.scss +3 -5
|
@@ -1,16 +1,22 @@
|
|
|
1
|
+
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
2
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
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
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
|
|
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); }
|
|
1
6
|
import React, { useEffect, useState } from "react";
|
|
2
7
|
import { faTimes } from "@fortawesome/free-solid-svg-icons";
|
|
3
8
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
|
4
9
|
import _ from "lodash";
|
|
5
10
|
import { Alert, Button, ListGroup } from "react-bootstrap";
|
|
6
11
|
import ButtonGroup from "react-bootstrap/ButtonGroup";
|
|
7
|
-
import { SELECTION_MODES, VAR_SORT } from "../../constants/constants";
|
|
8
|
-
import { useDataset, useDatasetDispatch } from "../../context/DatasetContext";
|
|
9
|
-
import { LoadingSpinner } from "../../utils/LoadingIndicators";
|
|
10
|
-
import { useFetch } from "../../utils/requests";
|
|
11
12
|
import { VarItem } from "./VarItem";
|
|
12
13
|
import { VarListToolbar } from "./VarListToolbar";
|
|
13
14
|
import { VarSet } from "./VarSet";
|
|
15
|
+
import { SELECTION_MODES, VAR_SORT } from "../../constants/constants";
|
|
16
|
+
import { useDataset } from "../../context/DatasetContext";
|
|
17
|
+
import { useSettings, useSettingsDispatch } from "../../context/SettingsContext";
|
|
18
|
+
import { LoadingSpinner } from "../../utils/LoadingIndicators";
|
|
19
|
+
import { useFetch } from "../../utils/requests";
|
|
14
20
|
const useVarMean = function (varKeys) {
|
|
15
21
|
let enabled = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
|
16
22
|
const ENDPOINT = "matrix/mean";
|
|
@@ -26,13 +32,12 @@ const useVarMean = function (varKeys) {
|
|
|
26
32
|
});
|
|
27
33
|
useEffect(() => {
|
|
28
34
|
setParams(p => {
|
|
29
|
-
return {
|
|
30
|
-
...p,
|
|
35
|
+
return _objectSpread(_objectSpread({}, p), {}, {
|
|
31
36
|
varKeys: _.map(varKeys, v => v.isSet ? {
|
|
32
37
|
name: v.name,
|
|
33
38
|
indices: v.vars.map(v => v.index)
|
|
34
39
|
} : v.index)
|
|
35
|
-
};
|
|
40
|
+
});
|
|
36
41
|
});
|
|
37
42
|
}, [varKeys]);
|
|
38
43
|
return useFetch(ENDPOINT, params, {
|
|
@@ -45,173 +50,50 @@ const useVarMean = function (varKeys) {
|
|
|
45
50
|
const sortMeans = (i, means) => {
|
|
46
51
|
return means[i.name] || _.min(_.values(means)) - 1;
|
|
47
52
|
};
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
// add to disease dataset metadata
|
|
51
|
-
function DiseaseVarList(_ref) {
|
|
52
|
-
let {
|
|
53
|
-
makeListItem
|
|
54
|
-
} = _ref;
|
|
55
|
-
const ENDPOINT = "disease/genes";
|
|
56
|
-
const dataset = useDataset();
|
|
57
|
-
const dispatch = useDatasetDispatch();
|
|
58
|
-
const [diseaseVars, setDiseaseVars] = useState([]);
|
|
59
|
-
const [sortedDiseaseVars, setSortedDiseaseVars] = useState([]);
|
|
60
|
-
const [params, setParams] = useState({
|
|
61
|
-
url: dataset.url,
|
|
62
|
-
col: dataset.varNamesCol,
|
|
63
|
-
diseaseId: dataset.selectedDisease?.id,
|
|
64
|
-
diseaseDatasets: dataset.diseaseDatasets
|
|
65
|
-
});
|
|
66
|
-
useEffect(() => {
|
|
67
|
-
setParams(p => {
|
|
68
|
-
return {
|
|
69
|
-
...p,
|
|
70
|
-
diseaseId: dataset.selectedDisease?.id
|
|
71
|
-
};
|
|
72
|
-
});
|
|
73
|
-
}, [dataset.selectedDisease]);
|
|
74
|
-
const diseaseData = useFetch(ENDPOINT, params, {
|
|
75
|
-
enabled: !!params.diseaseId,
|
|
76
|
-
refetchOnMount: false
|
|
77
|
-
});
|
|
78
|
-
useEffect(() => {
|
|
79
|
-
if (!diseaseData.isPending && !diseaseData.serverError) {
|
|
80
|
-
setDiseaseVars(diseaseData.fetchedData);
|
|
81
|
-
}
|
|
82
|
-
}, [diseaseData.fetchedData, diseaseData.isPending, diseaseData.serverError]);
|
|
83
|
-
const varMeans = useVarMean(diseaseVars, !!diseaseVars?.length && dataset.varSort.disease.sort === VAR_SORT.MATRIX);
|
|
84
|
-
useEffect(() => {
|
|
85
|
-
if (dataset.varSort.disease.sort === VAR_SORT.MATRIX) {
|
|
86
|
-
if (!varMeans.isPending && !varMeans.serverError) {
|
|
87
|
-
setSortedDiseaseVars(_.orderBy(diseaseVars, o => {
|
|
88
|
-
return sortMeans(o, varMeans.fetchedData);
|
|
89
|
-
}, dataset.varSort.disease.sortOrder));
|
|
90
|
-
}
|
|
91
|
-
} else if (dataset.varSort.disease.sort === VAR_SORT.NAME) {
|
|
92
|
-
setSortedDiseaseVars(_.orderBy(diseaseVars, "name", dataset.varSort.disease.sortOrder));
|
|
93
|
-
} else {
|
|
94
|
-
setSortedDiseaseVars(diseaseVars);
|
|
95
|
-
}
|
|
96
|
-
}, [dataset.varSort.disease.sort, dataset.varSort.disease.sortOrder, diseaseVars, varMeans.fetchedData, varMeans.isPending, varMeans.serverError]);
|
|
97
|
-
const diseaseVarList = _.map(sortedDiseaseVars, item => {
|
|
98
|
-
return makeListItem(item, true);
|
|
99
|
-
});
|
|
100
|
-
const isPending = diseaseData.isPending || varMeans.isPending && dataset.varSort.disease.sort === VAR_SORT.MATRIX;
|
|
101
|
-
return /*#__PURE__*/React.createElement(React.Fragment, null, dataset.selectedDisease && (!isPending && !diseaseVars?.length ? /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
|
|
102
|
-
className: "d-flex justify-content-between mt-3"
|
|
103
|
-
}, /*#__PURE__*/React.createElement("h5", null, "Disease genes")), /*#__PURE__*/React.createElement(Alert, {
|
|
104
|
-
variant: "light"
|
|
105
|
-
}, "No disease genes found.")) : /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
|
|
106
|
-
className: "d-flex justify-content-between my-2"
|
|
107
|
-
}, /*#__PURE__*/React.createElement("h5", null, "Disease genes"), /*#__PURE__*/React.createElement(ButtonGroup, {
|
|
108
|
-
"aria-label": "Feature options",
|
|
109
|
-
size: "sm"
|
|
110
|
-
}, /*#__PURE__*/React.createElement(Button, {
|
|
111
|
-
variant: "info",
|
|
112
|
-
onClick: () => {
|
|
113
|
-
dispatch({
|
|
114
|
-
type: "reset.disease"
|
|
115
|
-
});
|
|
116
|
-
}
|
|
117
|
-
}, /*#__PURE__*/React.createElement(FontAwesomeIcon, {
|
|
118
|
-
icon: faTimes,
|
|
119
|
-
className: "me-1"
|
|
120
|
-
}), "Clear"))), /*#__PURE__*/React.createElement("p", null, dataset.selectedDisease?.name), /*#__PURE__*/React.createElement(VarListToolbar, {
|
|
121
|
-
varType: "disease"
|
|
122
|
-
}), /*#__PURE__*/React.createElement("div", {
|
|
123
|
-
className: "position-relative"
|
|
124
|
-
}, isPending && /*#__PURE__*/React.createElement(LoadingSpinner, null), /*#__PURE__*/React.createElement(ListGroup, {
|
|
125
|
-
variant: "flush",
|
|
126
|
-
className: "cherita-list"
|
|
127
|
-
}, diseaseVarList)))));
|
|
128
|
-
}
|
|
129
|
-
export function VarNamesList(_ref2) {
|
|
53
|
+
export function VarNamesList(_ref) {
|
|
54
|
+
var _settings$selectedVar, _settings$selectedVar2;
|
|
130
55
|
let {
|
|
131
56
|
mode = SELECTION_MODES.SINGLE,
|
|
132
|
-
displayName = "genes"
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
const
|
|
136
|
-
const
|
|
137
|
-
const [
|
|
138
|
-
const [active, setActive] = useState(mode === SELECTION_MODES.SINGLE ? dataset.selectedVar?.matrix_index || dataset.selectedVar?.name : dataset.selectedMultiVar.map(i => i.matrix_index || i.name));
|
|
139
|
-
const [sortedVarButtons, setSortedVarButtons] = useState([]);
|
|
57
|
+
displayName = "genes"
|
|
58
|
+
} = _ref;
|
|
59
|
+
const settings = useSettings();
|
|
60
|
+
const dispatch = useSettingsDispatch();
|
|
61
|
+
const [active, setActive] = useState(mode === SELECTION_MODES.SINGLE ? ((_settings$selectedVar = settings.selectedVar) === null || _settings$selectedVar === void 0 ? void 0 : _settings$selectedVar.matrix_index) || ((_settings$selectedVar2 = settings.selectedVar) === null || _settings$selectedVar2 === void 0 ? void 0 : _settings$selectedVar2.name) : settings.selectedMultiVar.map(i => i.matrix_index || i.name));
|
|
62
|
+
const [sortedVars, setSortedVars] = useState([]);
|
|
140
63
|
useEffect(() => {
|
|
141
64
|
if (mode === SELECTION_MODES.SINGLE) {
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
return _.unionWith(v, [dataset.selectedVar], _.isEqual);
|
|
145
|
-
} else {
|
|
146
|
-
return v;
|
|
147
|
-
}
|
|
148
|
-
});
|
|
149
|
-
setActive(dataset.selectedVar?.matrix_index || dataset.selectedVar?.name);
|
|
65
|
+
var _settings$selectedVar3, _settings$selectedVar4;
|
|
66
|
+
setActive(((_settings$selectedVar3 = settings.selectedVar) === null || _settings$selectedVar3 === void 0 ? void 0 : _settings$selectedVar3.matrix_index) || ((_settings$selectedVar4 = settings.selectedVar) === null || _settings$selectedVar4 === void 0 ? void 0 : _settings$selectedVar4.name));
|
|
150
67
|
}
|
|
151
|
-
}, [mode,
|
|
68
|
+
}, [mode, settings.selectedVar]);
|
|
152
69
|
useEffect(() => {
|
|
153
70
|
if (mode === SELECTION_MODES.MULTIPLE) {
|
|
154
|
-
|
|
155
|
-
if (dataset.selectedMultiVar.length) {
|
|
156
|
-
return _.unionWith(v, dataset.selectedMultiVar, _.isEqual);
|
|
157
|
-
} else {
|
|
158
|
-
return v;
|
|
159
|
-
}
|
|
160
|
-
});
|
|
161
|
-
setActive(dataset.selectedMultiVar.map(i => i.matrix_index || i.name));
|
|
71
|
+
setActive(settings.selectedMultiVar.map(i => i.matrix_index || i.name));
|
|
162
72
|
}
|
|
163
|
-
}, [mode,
|
|
164
|
-
|
|
165
|
-
setVarButtons(v => {
|
|
166
|
-
const updated = _.compact(_.map(v, i => {
|
|
167
|
-
if (i.isSet) {
|
|
168
|
-
return dataset.varSets.find(s => s.name === i.name);
|
|
169
|
-
} else return i;
|
|
170
|
-
}));
|
|
171
|
-
const newSets = _.difference(dataset.varSets, updated);
|
|
172
|
-
return [...updated, ...newSets];
|
|
173
|
-
});
|
|
174
|
-
if (mode === SELECTION_MODES.SINGLE) {
|
|
175
|
-
if (dataset.selectedVar?.isSet) {
|
|
176
|
-
const selectedSet = dataset.varSets.find(s => s.name === dataset.selectedVar.name);
|
|
177
|
-
dispatch({
|
|
178
|
-
type: "select.var",
|
|
179
|
-
var: selectedSet
|
|
180
|
-
});
|
|
181
|
-
}
|
|
182
|
-
} else {
|
|
183
|
-
dispatch({
|
|
184
|
-
type: "update.multivar",
|
|
185
|
-
vars: dataset.varSets
|
|
186
|
-
});
|
|
187
|
-
}
|
|
188
|
-
}, [mode, dataset.varSets, dataset.selectedVar?.isSet, dataset.selectedVar?.name, dispatch]);
|
|
189
|
-
const varMeans = useVarMean(varButtons, dataset.varSort.var.sort === VAR_SORT.MATRIX);
|
|
73
|
+
}, [mode, settings.selectedMultiVar]);
|
|
74
|
+
const varMeans = useVarMean(settings.vars, settings.varSort.var.sort === VAR_SORT.MATRIX);
|
|
190
75
|
|
|
191
|
-
// @TODO: deferr
|
|
76
|
+
// @TODO: deferr sortedVars ?
|
|
192
77
|
useEffect(() => {
|
|
193
|
-
if (
|
|
78
|
+
if (settings.varSort.var.sort === VAR_SORT.MATRIX) {
|
|
194
79
|
if (!varMeans.isPending && !varMeans.serverError && varMeans.fetchedData) {
|
|
195
|
-
|
|
80
|
+
setSortedVars(_.orderBy(settings.vars, o => {
|
|
196
81
|
return sortMeans(o, varMeans.fetchedData);
|
|
197
|
-
},
|
|
82
|
+
}, settings.varSort.var.sortOrder));
|
|
198
83
|
}
|
|
199
|
-
} else if (
|
|
200
|
-
|
|
84
|
+
} else if (settings.varSort.var.sort === VAR_SORT.NAME) {
|
|
85
|
+
setSortedVars(_.orderBy(settings.vars, "name", settings.varSort.var.sortOrder));
|
|
201
86
|
} else {
|
|
202
|
-
|
|
87
|
+
setSortedVars(settings.vars);
|
|
203
88
|
}
|
|
204
|
-
}, [
|
|
205
|
-
const makeListItem =
|
|
206
|
-
let isDiseaseGene = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
|
89
|
+
}, [settings.varSort.var.sort, settings.varSort.var.sortOrder, varMeans.isPending, varMeans.serverError, varMeans.fetchedData, settings.vars]);
|
|
90
|
+
const makeListItem = item => {
|
|
207
91
|
return /*#__PURE__*/React.createElement(ListGroup.Item, {
|
|
208
92
|
key: item.matrix_index
|
|
209
93
|
}, /*#__PURE__*/React.createElement(VarItem, {
|
|
210
94
|
item: item,
|
|
211
95
|
active: active,
|
|
212
|
-
|
|
213
|
-
mode: mode,
|
|
214
|
-
isDiseaseGene: isDiseaseGene
|
|
96
|
+
mode: mode
|
|
215
97
|
}));
|
|
216
98
|
};
|
|
217
99
|
const makeSetListItem = set => {
|
|
@@ -223,7 +105,7 @@ export function VarNamesList(_ref2) {
|
|
|
223
105
|
mode: mode
|
|
224
106
|
}));
|
|
225
107
|
};
|
|
226
|
-
const varList = _.map(
|
|
108
|
+
const varList = _.map(sortedVars, item => {
|
|
227
109
|
if (item.isSet) {
|
|
228
110
|
return makeSetListItem(item);
|
|
229
111
|
} else {
|
|
@@ -232,17 +114,17 @@ export function VarNamesList(_ref2) {
|
|
|
232
114
|
});
|
|
233
115
|
const newSetName = () => {
|
|
234
116
|
let n = 1;
|
|
235
|
-
let setName =
|
|
236
|
-
const
|
|
237
|
-
return
|
|
117
|
+
let setName = "Set ".concat(n);
|
|
118
|
+
const nameExists = name => {
|
|
119
|
+
return settings.vars.some(v => v.name === name);
|
|
238
120
|
};
|
|
239
|
-
while (
|
|
121
|
+
while (nameExists(setName)) {
|
|
240
122
|
n++;
|
|
241
|
-
setName =
|
|
123
|
+
setName = "Set ".concat(n);
|
|
242
124
|
}
|
|
243
125
|
return setName;
|
|
244
126
|
};
|
|
245
|
-
const isPending = varMeans.isPending &&
|
|
127
|
+
const isPending = varMeans.isPending && settings.varSort.var.sort === VAR_SORT.MATRIX;
|
|
246
128
|
return /*#__PURE__*/React.createElement("div", {
|
|
247
129
|
className: "position-relative"
|
|
248
130
|
}, /*#__PURE__*/React.createElement("div", {
|
|
@@ -256,8 +138,8 @@ export function VarNamesList(_ref2) {
|
|
|
256
138
|
variant: "info",
|
|
257
139
|
onClick: () => {
|
|
258
140
|
dispatch({
|
|
259
|
-
type: "add.
|
|
260
|
-
|
|
141
|
+
type: "add.var",
|
|
142
|
+
var: {
|
|
261
143
|
name: newSetName(),
|
|
262
144
|
vars: [],
|
|
263
145
|
isSet: true
|
|
@@ -267,12 +149,8 @@ export function VarNamesList(_ref2) {
|
|
|
267
149
|
}, "New set"), /*#__PURE__*/React.createElement(Button, {
|
|
268
150
|
variant: "info",
|
|
269
151
|
onClick: () => {
|
|
270
|
-
setVarButtons([]);
|
|
271
|
-
dispatch({
|
|
272
|
-
type: mode === SELECTION_MODES.SINGLE ? "reset.var" : "reset.multiVar"
|
|
273
|
-
});
|
|
274
152
|
dispatch({
|
|
275
|
-
type: "reset.
|
|
153
|
+
type: "reset.vars"
|
|
276
154
|
});
|
|
277
155
|
}
|
|
278
156
|
}, /*#__PURE__*/React.createElement(FontAwesomeIcon, {
|
|
@@ -285,7 +163,5 @@ export function VarNamesList(_ref2) {
|
|
|
285
163
|
}, isPending && /*#__PURE__*/React.createElement(LoadingSpinner, null), /*#__PURE__*/React.createElement(ListGroup, {
|
|
286
164
|
variant: "flush",
|
|
287
165
|
className: "cherita-list"
|
|
288
|
-
}, varList))))
|
|
289
|
-
makeListItem: makeListItem
|
|
290
|
-
}))));
|
|
166
|
+
}, varList))))));
|
|
291
167
|
}
|
|
@@ -3,18 +3,18 @@ import { faArrowDown19, faArrowDownAZ, faArrowUp91, faArrowUpZA, faXmark } from
|
|
|
3
3
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
|
4
4
|
import { ToggleButton, ToggleButtonGroup } from "react-bootstrap";
|
|
5
5
|
import { VAR_SORT, VAR_SORT_ORDER } from "../../constants/constants";
|
|
6
|
-
import {
|
|
6
|
+
import { useSettings, useSettingsDispatch } from "../../context/SettingsContext";
|
|
7
7
|
|
|
8
8
|
// @TODO: set option for "var" and "disease"
|
|
9
9
|
export function VarListToolbar(_ref) {
|
|
10
10
|
let {
|
|
11
11
|
varType = "var"
|
|
12
12
|
} = _ref;
|
|
13
|
-
const
|
|
14
|
-
const dispatch =
|
|
15
|
-
const [sort, setSort] = useState(
|
|
16
|
-
const [nameSortOrder, setNameSortOrder] = useState(
|
|
17
|
-
const [matrixSortOrder, setMatrixSortOrder] = useState(
|
|
13
|
+
const settings = useSettings();
|
|
14
|
+
const dispatch = useSettingsDispatch();
|
|
15
|
+
const [sort, setSort] = useState(settings.varSort.var.sort);
|
|
16
|
+
const [nameSortOrder, setNameSortOrder] = useState(settings.varSort.var.sortOrder);
|
|
17
|
+
const [matrixSortOrder, setMatrixSortOrder] = useState(settings.varSort.var.sortOrder);
|
|
18
18
|
const handleSort = (sortValue, sortOrder, setSortOrder) => {
|
|
19
19
|
if (sort !== sortValue) {
|
|
20
20
|
setSort(sortValue);
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
import React, { useState } from "react";
|
|
2
|
-
import { faCircleInfo, faDroplet, faTrash } from "@fortawesome/free-solid-svg-icons";
|
|
2
|
+
import { faChevronDown, faChevronUp, faCircleInfo, faDroplet, faPlus, faTrash } from "@fortawesome/free-solid-svg-icons";
|
|
3
3
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
|
4
|
-
import { List } from "@mui/icons-material";
|
|
5
4
|
import _ from "lodash";
|
|
6
5
|
import { Button, Collapse, ListGroup, OverlayTrigger, Tooltip } from "react-bootstrap";
|
|
6
|
+
import { SelectionItem } from "./VarItem";
|
|
7
7
|
import { COLOR_ENCODINGS, SELECTION_MODES } from "../../constants/constants";
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import { SingleSelectionItem } from "./VarItem";
|
|
8
|
+
import { useSettings, useSettingsDispatch } from "../../context/SettingsContext";
|
|
9
|
+
import { SearchModal } from "../search-bar/SearchBar";
|
|
11
10
|
|
|
12
11
|
// @TODO: add button to score genes and plot
|
|
13
12
|
|
|
@@ -18,20 +17,22 @@ const addVarToSet = (dispatch, set, v) => {
|
|
|
18
17
|
var: v
|
|
19
18
|
});
|
|
20
19
|
};
|
|
21
|
-
function
|
|
20
|
+
function SelectionSet(_ref) {
|
|
22
21
|
let {
|
|
23
22
|
set,
|
|
24
23
|
isActive,
|
|
25
24
|
selectSet,
|
|
26
25
|
removeSet,
|
|
27
26
|
removeSetVar,
|
|
28
|
-
|
|
27
|
+
isMultiple = false
|
|
29
28
|
} = _ref;
|
|
30
29
|
const [openSet, setOpenSet] = useState(false);
|
|
30
|
+
const [showModal, setShowModal] = useState(false);
|
|
31
|
+
const [searchText, setSearchText] = useState("");
|
|
31
32
|
const varList = set.vars.length ? _.map(set.vars, v => {
|
|
32
33
|
return /*#__PURE__*/React.createElement(ListGroup.Item, {
|
|
33
34
|
key: v.name
|
|
34
|
-
}, /*#__PURE__*/React.createElement(
|
|
35
|
+
}, /*#__PURE__*/React.createElement(SelectionItem, {
|
|
35
36
|
item: v,
|
|
36
37
|
showSetColorEncoding: false,
|
|
37
38
|
removeVar: () => removeSetVar(v)
|
|
@@ -46,16 +47,37 @@ function SingleSelectionSet(_ref) {
|
|
|
46
47
|
}
|
|
47
48
|
}, /*#__PURE__*/React.createElement("div", {
|
|
48
49
|
className: "d-flex justify-content-between align-items-center w-100"
|
|
49
|
-
}, /*#__PURE__*/React.createElement("div",
|
|
50
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
51
|
+
className: "ellipsis-text",
|
|
52
|
+
title: set.name
|
|
53
|
+
}, set.name), /*#__PURE__*/React.createElement("div", {
|
|
50
54
|
className: "d-flex align-items-center gap-1"
|
|
51
55
|
}, /*#__PURE__*/React.createElement(OverlayTrigger, {
|
|
52
56
|
placement: "top",
|
|
53
57
|
overlay: /*#__PURE__*/React.createElement(Tooltip, null, "This set represents the mean value of its features")
|
|
54
58
|
}, /*#__PURE__*/React.createElement(FontAwesomeIcon, {
|
|
55
59
|
icon: faCircleInfo
|
|
56
|
-
})), /*#__PURE__*/React.createElement(
|
|
60
|
+
})), /*#__PURE__*/React.createElement(Button, {
|
|
61
|
+
type: "button",
|
|
62
|
+
variant: "outline-primary",
|
|
63
|
+
className: "m-0 p-0 px-1",
|
|
64
|
+
disabled: !set.vars.length,
|
|
65
|
+
title: "Open set"
|
|
66
|
+
}, /*#__PURE__*/React.createElement(FontAwesomeIcon, {
|
|
67
|
+
icon: openSet ? faChevronUp : faChevronDown
|
|
68
|
+
})), /*#__PURE__*/React.createElement(Button, {
|
|
69
|
+
type: "button",
|
|
70
|
+
variant: "outline-primary",
|
|
71
|
+
className: "m-0 p-0 px-1",
|
|
72
|
+
onClick: e => {
|
|
73
|
+
e.stopPropagation();
|
|
74
|
+
setShowModal(true);
|
|
75
|
+
},
|
|
76
|
+
title: "Add to set"
|
|
77
|
+
}, /*#__PURE__*/React.createElement(FontAwesomeIcon, {
|
|
78
|
+
icon: faPlus
|
|
79
|
+
})), /*#__PURE__*/React.createElement(Button, {
|
|
57
80
|
type: "button",
|
|
58
|
-
key: set.name,
|
|
59
81
|
variant: isActive ? "primary" : "outline-primary",
|
|
60
82
|
className: "m-0 p-0 px-1",
|
|
61
83
|
onClick: e => {
|
|
@@ -66,6 +88,10 @@ function SingleSelectionSet(_ref) {
|
|
|
66
88
|
title: "Set as color encoding"
|
|
67
89
|
}, /*#__PURE__*/React.createElement(FontAwesomeIcon, {
|
|
68
90
|
icon: faDroplet
|
|
91
|
+
}), isMultiple && /*#__PURE__*/React.createElement(FontAwesomeIcon, {
|
|
92
|
+
icon: faPlus,
|
|
93
|
+
size: "xs",
|
|
94
|
+
className: "ps-xs-1"
|
|
69
95
|
})), /*#__PURE__*/React.createElement(Button, {
|
|
70
96
|
type: "button",
|
|
71
97
|
className: "m-0 p-0 px-1",
|
|
@@ -81,45 +107,30 @@ function SingleSelectionSet(_ref) {
|
|
|
81
107
|
in: openSet
|
|
82
108
|
}, /*#__PURE__*/React.createElement("div", {
|
|
83
109
|
className: "mt-2"
|
|
84
|
-
}, showSearchBar &&
|
|
85
|
-
/*#__PURE__*/
|
|
86
|
-
// @TODO: fix how results are displayed, should be placed on top of parent components
|
|
87
|
-
React.createElement(SearchBar, {
|
|
88
|
-
handleSelect: (d, i) => addVarToSet(d, set, i)
|
|
89
|
-
}), /*#__PURE__*/React.createElement("div", {
|
|
90
|
-
className: "mx-2"
|
|
91
110
|
}, /*#__PURE__*/React.createElement(ListGroup, {
|
|
92
111
|
variant: "flush",
|
|
93
|
-
className: "cherita-list"
|
|
94
|
-
}, varList)))
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
}, /*#__PURE__*/React.createElement(Button, {
|
|
107
|
-
type: "button",
|
|
108
|
-
key: set.name,
|
|
109
|
-
variant: isActive ? "primary" : "outline-primary",
|
|
110
|
-
className: "m-0 p-0 px-1",
|
|
111
|
-
onClick: toggleSet,
|
|
112
|
-
title: set.name
|
|
113
|
-
}, set.name))));
|
|
112
|
+
className: "cherita-list var-set-list"
|
|
113
|
+
}, varList))), /*#__PURE__*/React.createElement(SearchModal, {
|
|
114
|
+
show: showModal,
|
|
115
|
+
handleClose: () => setShowModal(false),
|
|
116
|
+
text: searchText,
|
|
117
|
+
setText: setSearchText,
|
|
118
|
+
displayText: "features",
|
|
119
|
+
handleSelect: (d, i) => {
|
|
120
|
+
addVarToSet(d, set, i);
|
|
121
|
+
},
|
|
122
|
+
searchVar: true,
|
|
123
|
+
searchDiseases: false
|
|
124
|
+
}));
|
|
114
125
|
}
|
|
115
|
-
export function VarSet(
|
|
126
|
+
export function VarSet(_ref2) {
|
|
116
127
|
let {
|
|
117
128
|
set,
|
|
118
129
|
active,
|
|
119
130
|
mode = SELECTION_MODES.SINGLE
|
|
120
|
-
} =
|
|
121
|
-
const
|
|
122
|
-
const dispatch =
|
|
131
|
+
} = _ref2;
|
|
132
|
+
const settings = useSettings();
|
|
133
|
+
const dispatch = useSettingsDispatch();
|
|
123
134
|
const selectSet = () => {
|
|
124
135
|
if (mode === SELECTION_MODES.SINGLE) {
|
|
125
136
|
dispatch({
|
|
@@ -153,8 +164,8 @@ export function VarSet(_ref3) {
|
|
|
153
164
|
}
|
|
154
165
|
}
|
|
155
166
|
dispatch({
|
|
156
|
-
type: "remove.
|
|
157
|
-
|
|
167
|
+
type: "remove.var",
|
|
168
|
+
var: set
|
|
158
169
|
});
|
|
159
170
|
};
|
|
160
171
|
const removeSetVar = v => {
|
|
@@ -165,28 +176,27 @@ export function VarSet(_ref3) {
|
|
|
165
176
|
});
|
|
166
177
|
};
|
|
167
178
|
const toggleSet = () => {
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
});
|
|
173
|
-
} else {
|
|
174
|
-
selectSet();
|
|
175
|
-
}
|
|
179
|
+
dispatch({
|
|
180
|
+
type: "toggle.multivar",
|
|
181
|
+
var: set
|
|
182
|
+
});
|
|
176
183
|
};
|
|
177
184
|
if (set && mode === SELECTION_MODES.SINGLE) {
|
|
178
|
-
return /*#__PURE__*/React.createElement(
|
|
185
|
+
return /*#__PURE__*/React.createElement(SelectionSet, {
|
|
179
186
|
set: set,
|
|
180
|
-
isActive:
|
|
187
|
+
isActive: settings.colorEncoding === COLOR_ENCODINGS.VAR && active === set.name,
|
|
181
188
|
selectSet: selectSet,
|
|
182
189
|
removeSet: removeSet,
|
|
183
190
|
removeSetVar: v => removeSetVar(v)
|
|
184
191
|
});
|
|
185
192
|
} else if (mode === SELECTION_MODES.MULTIPLE) {
|
|
186
|
-
return /*#__PURE__*/React.createElement(
|
|
193
|
+
return /*#__PURE__*/React.createElement(SelectionSet, {
|
|
187
194
|
set: set,
|
|
188
195
|
isActive: _.includes(active, set.name),
|
|
189
|
-
|
|
196
|
+
selectSet: toggleSet,
|
|
197
|
+
removeSet: removeSet,
|
|
198
|
+
removeSetVar: v => removeSetVar(v),
|
|
199
|
+
isMultiple: true
|
|
190
200
|
});
|
|
191
201
|
} else {
|
|
192
202
|
return null;
|