@haniffalab/cherita-react 0.2.0-dev.2024-04-04.0af834c7 → 0.2.0-dev.2024-05-09.07fb18ed
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/Offcanvas/index.js +6 -3
- package/dist/components/dotplot/Dotplot.js +7 -5
- package/dist/components/heatmap/Heatmap.js +5 -3
- package/dist/components/matrixplot/Matrixplot.js +7 -5
- package/dist/components/scatterplot/Legend.js +4 -4
- package/dist/components/scatterplot/Scatterplot.js +6 -7
- package/dist/components/search-bar/SearchBar.js +75 -0
- package/dist/components/search-bar/SearchResults.js +166 -0
- package/dist/components/var-list/VarList.js +82 -168
- package/dist/components/violin/Violin.js +24 -6
- package/dist/context/DatasetContext.js +52 -9
- package/dist/helpers/color-helper.js +15 -12
- package/dist/index.js +7 -0
- package/dist/utils/requests.js +20 -3
- package/dist/utils/search.js +93 -0
- package/package.json +2 -2
|
@@ -11,6 +11,7 @@ exports.OffcanvasVars = OffcanvasVars;
|
|
|
11
11
|
var _react = require("react");
|
|
12
12
|
var _Offcanvas = _interopRequireDefault(require("react-bootstrap/Offcanvas"));
|
|
13
13
|
var _cheritaReact = require("@haniffalab/cherita-react");
|
|
14
|
+
var _SearchBar = require("../search-bar/SearchBar");
|
|
14
15
|
var _jsxRuntime = require("react/jsx-runtime");
|
|
15
16
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
16
17
|
function OffcanvasObs(_ref) {
|
|
@@ -65,10 +66,12 @@ function OffcanvasVars(_ref3) {
|
|
|
65
66
|
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Offcanvas.default.Title, {
|
|
66
67
|
children: "Features"
|
|
67
68
|
})
|
|
68
|
-
}), /*#__PURE__*/(0, _jsxRuntime.
|
|
69
|
-
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(
|
|
69
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_Offcanvas.default.Body, {
|
|
70
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_SearchBar.SearchBar, {
|
|
71
|
+
searchDiseases: true
|
|
72
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_cheritaReact.VarNamesList, {
|
|
70
73
|
mode: mode
|
|
71
|
-
})
|
|
74
|
+
})]
|
|
72
75
|
})]
|
|
73
76
|
});
|
|
74
77
|
}
|
|
@@ -209,10 +209,11 @@ function Dotplot() {
|
|
|
209
209
|
const [params, setParams] = (0, _react.useState)({
|
|
210
210
|
url: dataset.url,
|
|
211
211
|
selectedObs: dataset.selectedObs,
|
|
212
|
-
selectedMultiVar: dataset.selectedMultiVar.map(i => i.
|
|
212
|
+
selectedMultiVar: dataset.selectedMultiVar.map(i => i.index),
|
|
213
213
|
standardScale: dataset.controls.standardScale,
|
|
214
214
|
meanOnlyExpressed: dataset.controls.meanOnlyExpressed,
|
|
215
|
-
expressionCutoff: dataset.controls.expressionCutoff
|
|
215
|
+
expressionCutoff: dataset.controls.expressionCutoff,
|
|
216
|
+
varNamesCol: dataset.varNamesCol
|
|
216
217
|
});
|
|
217
218
|
// @TODO: set default scale
|
|
218
219
|
|
|
@@ -227,13 +228,14 @@ function Dotplot() {
|
|
|
227
228
|
...p,
|
|
228
229
|
url: dataset.url,
|
|
229
230
|
selectedObs: dataset.selectedObs,
|
|
230
|
-
selectedMultiVar: dataset.selectedMultiVar.map(i => i.
|
|
231
|
+
selectedMultiVar: dataset.selectedMultiVar.map(i => i.index),
|
|
231
232
|
standardScale: dataset.controls.standardScale,
|
|
232
233
|
meanOnlyExpressed: dataset.controls.meanOnlyExpressed,
|
|
233
|
-
expressionCutoff: dataset.controls.expressionCutoff
|
|
234
|
+
expressionCutoff: dataset.controls.expressionCutoff,
|
|
235
|
+
varNamesCol: dataset.varNamesCol
|
|
234
236
|
};
|
|
235
237
|
});
|
|
236
|
-
}, [dataset.url, dataset.selectedObs, dataset.selectedMultiVar, dataset.controls.standardScale, dataset.controls.meanOnlyExpressed, dataset.controls.expressionCutoff]);
|
|
238
|
+
}, [dataset.url, dataset.selectedObs, dataset.selectedMultiVar, dataset.controls.standardScale, dataset.controls.meanOnlyExpressed, dataset.controls.expressionCutoff, dataset.varNamesCol]);
|
|
237
239
|
const updateColorscale = (0, _react.useCallback)(colorscale => {
|
|
238
240
|
setLayout(l => {
|
|
239
241
|
return {
|
|
@@ -50,7 +50,8 @@ function Heatmap() {
|
|
|
50
50
|
const [params, setParams] = (0, _react.useState)({
|
|
51
51
|
url: dataset.url,
|
|
52
52
|
selectedObs: dataset.selectedObs,
|
|
53
|
-
selectedMultiVar: dataset.selectedMultiVar.map(i => i.
|
|
53
|
+
selectedMultiVar: dataset.selectedMultiVar.map(i => i.index),
|
|
54
|
+
varNamesCol: dataset.varNamesCol
|
|
54
55
|
});
|
|
55
56
|
(0, _react.useEffect)(() => {
|
|
56
57
|
if (dataset.selectedObs && dataset.selectedMultiVar.length) {
|
|
@@ -63,10 +64,11 @@ function Heatmap() {
|
|
|
63
64
|
...p,
|
|
64
65
|
url: dataset.url,
|
|
65
66
|
selectedObs: dataset.selectedObs,
|
|
66
|
-
selectedMultiVar: dataset.selectedMultiVar.map(i => i.
|
|
67
|
+
selectedMultiVar: dataset.selectedMultiVar.map(i => i.index),
|
|
68
|
+
varNamesCol: dataset.varNamesCol
|
|
67
69
|
};
|
|
68
70
|
});
|
|
69
|
-
}, [dataset.selectedMultiVar, dataset.selectedObs, dataset.url]);
|
|
71
|
+
}, [dataset.selectedMultiVar, dataset.selectedObs, dataset.url, dataset.varNamesCol]);
|
|
70
72
|
const updateColorscale = (0, _react.useCallback)(colorscale => {
|
|
71
73
|
setLayout(l => {
|
|
72
74
|
return {
|
|
@@ -78,8 +78,9 @@ function Matrixplot() {
|
|
|
78
78
|
const [params, setParams] = (0, _react.useState)({
|
|
79
79
|
url: dataset.url,
|
|
80
80
|
selectedObs: dataset.selectedObs,
|
|
81
|
-
selectedMultiVar: dataset.selectedMultiVar.map(i => i.
|
|
82
|
-
standardScale: dataset.controls.standardScale
|
|
81
|
+
selectedMultiVar: dataset.selectedMultiVar.map(i => i.index),
|
|
82
|
+
standardScale: dataset.controls.standardScale,
|
|
83
|
+
varNamesCol: dataset.varNamesCol
|
|
83
84
|
});
|
|
84
85
|
(0, _react.useEffect)(() => {
|
|
85
86
|
if (dataset.selectedObs && dataset.selectedMultiVar.length) {
|
|
@@ -92,11 +93,12 @@ function Matrixplot() {
|
|
|
92
93
|
...p,
|
|
93
94
|
url: dataset.url,
|
|
94
95
|
selectedObs: dataset.selectedObs,
|
|
95
|
-
selectedMultiVar: dataset.selectedMultiVar.map(i => i.
|
|
96
|
-
standardScale: dataset.controls.standardScale
|
|
96
|
+
selectedMultiVar: dataset.selectedMultiVar.map(i => i.index),
|
|
97
|
+
standardScale: dataset.controls.standardScale,
|
|
98
|
+
varNamesCol: dataset.varNamesCol
|
|
97
99
|
};
|
|
98
100
|
});
|
|
99
|
-
}, [dataset.controls.standardScale, dataset.selectedMultiVar, dataset.selectedObs, dataset.url]);
|
|
101
|
+
}, [dataset.controls.standardScale, dataset.selectedMultiVar, dataset.selectedObs, dataset.url, dataset.varNamesCol]);
|
|
100
102
|
const updateColorscale = (0, _react.useCallback)(colorscale => {
|
|
101
103
|
setLayout(l => {
|
|
102
104
|
return {
|
|
@@ -43,7 +43,7 @@ function Legend(_ref) {
|
|
|
43
43
|
style: {
|
|
44
44
|
backgroundColor: color.hex()
|
|
45
45
|
}
|
|
46
|
-
}));
|
|
46
|
+
}, i));
|
|
47
47
|
}
|
|
48
48
|
return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
|
|
49
49
|
className: "cherita-legend",
|
|
@@ -51,13 +51,13 @@ function Legend(_ref) {
|
|
|
51
51
|
className: "gradient",
|
|
52
52
|
children: [legendList, /*#__PURE__*/(0, _jsxRuntime.jsx)("span", {
|
|
53
53
|
className: "domain-min",
|
|
54
|
-
children: dmin
|
|
54
|
+
children: dmin.toString()
|
|
55
55
|
}), /*#__PURE__*/(0, _jsxRuntime.jsx)("span", {
|
|
56
56
|
className: "domain-med",
|
|
57
|
-
children: (dmin + dmax) * 0.5
|
|
57
|
+
children: ((dmin + dmax) * 0.5).toString()
|
|
58
58
|
}), /*#__PURE__*/(0, _jsxRuntime.jsx)("span", {
|
|
59
59
|
className: "domain-max",
|
|
60
|
-
children: dmax
|
|
60
|
+
children: dmax.toString()
|
|
61
61
|
})]
|
|
62
62
|
})
|
|
63
63
|
});
|
|
@@ -7,8 +7,6 @@ exports.Scatterplot = Scatterplot;
|
|
|
7
7
|
exports.ScatterplotControls = ScatterplotControls;
|
|
8
8
|
require("bootstrap/dist/css/bootstrap.min.css");
|
|
9
9
|
var _react = _interopRequireWildcard(require("react"));
|
|
10
|
-
var _lodash = _interopRequireDefault(require("lodash"));
|
|
11
|
-
var _chromaJs = _interopRequireDefault(require("chroma-js"));
|
|
12
10
|
var _react2 = _interopRequireDefault(require("@deck.gl/react"));
|
|
13
11
|
var _layers = require("@deck.gl/layers");
|
|
14
12
|
var _layers2 = require("@nebula.gl/layers");
|
|
@@ -76,18 +74,19 @@ function Scatterplot(_ref) {
|
|
|
76
74
|
(0, _react.useEffect)(() => {
|
|
77
75
|
setData(function (prevState, props) {
|
|
78
76
|
const colorHelper = new _colorHelper.ColorHelper();
|
|
79
|
-
let scale = dataset.colorEncoding === "var" ? colorHelper.getScale(dataset, values) : null;
|
|
77
|
+
let scale = dataset.colorEncoding === "var" ? colorHelper.getScale(dataset.controls.colorScale, values) : null;
|
|
80
78
|
var data = position.map(function (e, i) {
|
|
79
|
+
var _dataset$obs$dataset$, _dataset$selectedObs;
|
|
81
80
|
return {
|
|
82
81
|
index: i,
|
|
83
82
|
position: [position[i][0], position[i][1]],
|
|
84
83
|
value: values[i],
|
|
85
|
-
color: colorHelper.getColor(dataset, values[i], scale)
|
|
84
|
+
color: colorHelper.getColor(dataset.colorEncoding, (_dataset$obs$dataset$ = dataset.obs[(_dataset$selectedObs = dataset.selectedObs) === null || _dataset$selectedObs === void 0 ? void 0 : _dataset$selectedObs.name]) === null || _dataset$obs$dataset$ === void 0 ? void 0 : _dataset$obs$dataset$.state, values[i], scale)
|
|
86
85
|
};
|
|
87
86
|
});
|
|
88
87
|
return data;
|
|
89
88
|
});
|
|
90
|
-
}, [position, values, dataset.controls.colorScale]);
|
|
89
|
+
}, [position, values, dataset.controls.colorScale, dataset.colorEncoding, dataset.obs, dataset.selectedObs]);
|
|
91
90
|
(0, _react.useEffect)(() => {
|
|
92
91
|
if (dataset.selectedObsm) {
|
|
93
92
|
const helper = new _mapHelper.MapHelper();
|
|
@@ -129,7 +128,7 @@ function Scatterplot(_ref) {
|
|
|
129
128
|
};
|
|
130
129
|
fetchData().catch(console.error);
|
|
131
130
|
}
|
|
132
|
-
}, [dataset.url, dataset.selectedVar]);
|
|
131
|
+
}, [dataset.url, dataset.selectedVar, dispatch]);
|
|
133
132
|
(0, _react.useEffect)(() => {
|
|
134
133
|
if (dataset.selectedObs) {
|
|
135
134
|
const zarrHelper = new _zarrHelper.ZarrHelper();
|
|
@@ -145,7 +144,7 @@ function Scatterplot(_ref) {
|
|
|
145
144
|
};
|
|
146
145
|
fetchData().catch(console.error);
|
|
147
146
|
}
|
|
148
|
-
}, [dataset.url, dataset.selectedObs]);
|
|
147
|
+
}, [dataset.url, dataset.selectedObs, dispatch]);
|
|
149
148
|
const layers = [new _layers.ScatterplotLayer({
|
|
150
149
|
id: "cherita-layer-scatterplot",
|
|
151
150
|
data,
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.SearchBar = SearchBar;
|
|
7
|
+
var _react = _interopRequireWildcard(require("react"));
|
|
8
|
+
var _lodash = _interopRequireDefault(require("lodash"));
|
|
9
|
+
var _reactBootstrap = require("react-bootstrap");
|
|
10
|
+
var _SearchResults = require("./SearchResults");
|
|
11
|
+
var _jsxRuntime = require("react/jsx-runtime");
|
|
12
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
13
|
+
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); }
|
|
14
|
+
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 && Object.prototype.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; }
|
|
15
|
+
function SearchBar(_ref) {
|
|
16
|
+
let {
|
|
17
|
+
searchVar = true,
|
|
18
|
+
searchDiseases = false
|
|
19
|
+
} = _ref;
|
|
20
|
+
const [showSuggestions, setShowSuggestions] = (0, _react.useState)(false);
|
|
21
|
+
const [text, setText] = (0, _react.useState)("");
|
|
22
|
+
const inputRef = (0, _react.useRef)(null);
|
|
23
|
+
const displayText = [...(searchVar ? ["features"] : []), ...(searchDiseases ? ["diseases"] : [])].join(" and ");
|
|
24
|
+
(0, _react.useEffect)(() => {
|
|
25
|
+
if (text.length > 0) {
|
|
26
|
+
setShowSuggestions(true);
|
|
27
|
+
}
|
|
28
|
+
}, [text]);
|
|
29
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
|
|
30
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Form, {
|
|
31
|
+
onSubmit: e => {
|
|
32
|
+
e.preventDefault();
|
|
33
|
+
},
|
|
34
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactBootstrap.FormGroup, {
|
|
35
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Form.Control, {
|
|
36
|
+
ref: inputRef,
|
|
37
|
+
onFocus: () => {
|
|
38
|
+
setShowSuggestions(text.length > 0);
|
|
39
|
+
},
|
|
40
|
+
onBlur: () => {
|
|
41
|
+
_lodash.default.delay(() => {
|
|
42
|
+
setShowSuggestions(false);
|
|
43
|
+
}, 150);
|
|
44
|
+
},
|
|
45
|
+
type: "text",
|
|
46
|
+
placeholder: "Search " + displayText,
|
|
47
|
+
value: text,
|
|
48
|
+
onChange: e => {
|
|
49
|
+
setText(e.target.value);
|
|
50
|
+
}
|
|
51
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Dropdown, {
|
|
52
|
+
show: showSuggestions,
|
|
53
|
+
onMouseDown: e => {
|
|
54
|
+
e.preventDefault();
|
|
55
|
+
},
|
|
56
|
+
onSelect: () => {
|
|
57
|
+
inputRef.current.blur();
|
|
58
|
+
},
|
|
59
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactBootstrap.Dropdown.Menu, {
|
|
60
|
+
style: {
|
|
61
|
+
width: "90%"
|
|
62
|
+
},
|
|
63
|
+
children: [searchVar && /*#__PURE__*/(0, _jsxRuntime.jsx)(_SearchResults.VarSearchResults, {
|
|
64
|
+
text: text,
|
|
65
|
+
setShowSuggestions: setShowSuggestions
|
|
66
|
+
}), searchVar && searchDiseases && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Dropdown.Divider, {}), searchDiseases && /*#__PURE__*/(0, _jsxRuntime.jsx)(_SearchResults.DiseasesSearchResults, {
|
|
67
|
+
text: text,
|
|
68
|
+
setShowSuggestions: setShowSuggestions
|
|
69
|
+
})]
|
|
70
|
+
})
|
|
71
|
+
})]
|
|
72
|
+
})
|
|
73
|
+
})
|
|
74
|
+
});
|
|
75
|
+
}
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.DiseasesSearchResults = DiseasesSearchResults;
|
|
7
|
+
exports.VarSearchResults = VarSearchResults;
|
|
8
|
+
var _react = _interopRequireWildcard(require("react"));
|
|
9
|
+
var _lodash = _interopRequireDefault(require("lodash"));
|
|
10
|
+
var _reactBootstrap = require("react-bootstrap");
|
|
11
|
+
var _DatasetContext = require("../../context/DatasetContext");
|
|
12
|
+
var _search = require("../../utils/search");
|
|
13
|
+
var _jsxRuntime = require("react/jsx-runtime");
|
|
14
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
15
|
+
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); }
|
|
16
|
+
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 && Object.prototype.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; }
|
|
17
|
+
function VarSearchResults(_ref) {
|
|
18
|
+
let {
|
|
19
|
+
text,
|
|
20
|
+
setShowSuggestions
|
|
21
|
+
} = _ref;
|
|
22
|
+
const [suggestions, setSuggestions] = (0, _react.useState)([]);
|
|
23
|
+
const {
|
|
24
|
+
setParams,
|
|
25
|
+
data: {
|
|
26
|
+
fetchedData = [],
|
|
27
|
+
isPending,
|
|
28
|
+
serverError
|
|
29
|
+
},
|
|
30
|
+
onSelect
|
|
31
|
+
} = (0, _search.useVarSearch)();
|
|
32
|
+
const deferredData = (0, _react.useDeferredValue)(suggestions);
|
|
33
|
+
const isStale = deferredData !== fetchedData;
|
|
34
|
+
const updateParams = (0, _react.useMemo)(() => {
|
|
35
|
+
const setData = text => {
|
|
36
|
+
if (text.length) {
|
|
37
|
+
setParams(p => {
|
|
38
|
+
return {
|
|
39
|
+
...p,
|
|
40
|
+
text: text
|
|
41
|
+
};
|
|
42
|
+
});
|
|
43
|
+
} else {
|
|
44
|
+
setSuggestions([]);
|
|
45
|
+
setShowSuggestions(false);
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
return _lodash.default.debounce(setData, 300);
|
|
49
|
+
}, [setParams, setShowSuggestions]);
|
|
50
|
+
(0, _react.useEffect)(() => {
|
|
51
|
+
updateParams(text);
|
|
52
|
+
}, [text, updateParams]);
|
|
53
|
+
(0, _react.useEffect)(() => {
|
|
54
|
+
if (!isPending && !serverError) {
|
|
55
|
+
setSuggestions(fetchedData);
|
|
56
|
+
setShowSuggestions(true);
|
|
57
|
+
}
|
|
58
|
+
}, [fetchedData, isPending, serverError, setShowSuggestions]);
|
|
59
|
+
const suggestionsList = (0, _react.useMemo)(() => {
|
|
60
|
+
return deferredData === null || deferredData === void 0 ? void 0 : deferredData.map(item => {
|
|
61
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Dropdown.Item, {
|
|
62
|
+
as: "button",
|
|
63
|
+
disabled: isStale,
|
|
64
|
+
onClick: () => {
|
|
65
|
+
onSelect(item);
|
|
66
|
+
_lodash.default.delay(() => {
|
|
67
|
+
setShowSuggestions(false);
|
|
68
|
+
}, 150);
|
|
69
|
+
},
|
|
70
|
+
children: item.name
|
|
71
|
+
}, item.name);
|
|
72
|
+
});
|
|
73
|
+
}, [deferredData, isStale, onSelect, setShowSuggestions]);
|
|
74
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
|
|
75
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Dropdown.Header, {
|
|
76
|
+
children: "Features"
|
|
77
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
|
|
78
|
+
style: {
|
|
79
|
+
maxHeight: "25vh",
|
|
80
|
+
overflowY: "scroll"
|
|
81
|
+
},
|
|
82
|
+
children: deferredData !== null && deferredData !== void 0 && deferredData.length ? suggestionsList : /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Dropdown.Item, {
|
|
83
|
+
as: "button",
|
|
84
|
+
disabled: true,
|
|
85
|
+
children: !serverError ? isStale || isPending ? "Loading..." : "No items found" : "Failed to fetch data"
|
|
86
|
+
}, "empty")
|
|
87
|
+
})]
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
function DiseasesSearchResults(_ref2) {
|
|
91
|
+
let {
|
|
92
|
+
text,
|
|
93
|
+
setShowSuggestions
|
|
94
|
+
} = _ref2;
|
|
95
|
+
const [suggestions, setSuggestions] = (0, _react.useState)([]);
|
|
96
|
+
const dispatch = (0, _DatasetContext.useDatasetDispatch)();
|
|
97
|
+
const {
|
|
98
|
+
setParams,
|
|
99
|
+
data: {
|
|
100
|
+
fetchedData = [],
|
|
101
|
+
isPending,
|
|
102
|
+
serverError
|
|
103
|
+
}
|
|
104
|
+
} = (0, _search.useDiseaseSearch)();
|
|
105
|
+
(0, _search.useGetDisease)();
|
|
106
|
+
const deferredData = (0, _react.useDeferredValue)(suggestions);
|
|
107
|
+
const isStale = deferredData !== fetchedData;
|
|
108
|
+
const updateParams = (0, _react.useMemo)(() => {
|
|
109
|
+
const setData = text => {
|
|
110
|
+
if (text.length) {
|
|
111
|
+
setParams(p => {
|
|
112
|
+
return {
|
|
113
|
+
...p,
|
|
114
|
+
text: text
|
|
115
|
+
};
|
|
116
|
+
});
|
|
117
|
+
} else {
|
|
118
|
+
setSuggestions([]);
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
return _lodash.default.debounce(setData, 300);
|
|
122
|
+
}, [setParams]);
|
|
123
|
+
(0, _react.useEffect)(() => {
|
|
124
|
+
updateParams(text);
|
|
125
|
+
}, [text, updateParams]);
|
|
126
|
+
(0, _react.useEffect)(() => {
|
|
127
|
+
if (!isPending && !serverError) {
|
|
128
|
+
setSuggestions(fetchedData);
|
|
129
|
+
setShowSuggestions(true);
|
|
130
|
+
}
|
|
131
|
+
}, [fetchedData, isPending, serverError, setShowSuggestions]);
|
|
132
|
+
const suggestionsList = (0, _react.useMemo)(() => {
|
|
133
|
+
return deferredData === null || deferredData === void 0 ? void 0 : deferredData.map(item => {
|
|
134
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Dropdown.Item, {
|
|
135
|
+
as: "button",
|
|
136
|
+
disabled: isStale,
|
|
137
|
+
onClick: () => {
|
|
138
|
+
dispatch({
|
|
139
|
+
type: "select.disease",
|
|
140
|
+
id: item === null || item === void 0 ? void 0 : item.disease_id,
|
|
141
|
+
name: item === null || item === void 0 ? void 0 : item.disease_name
|
|
142
|
+
});
|
|
143
|
+
_lodash.default.delay(() => {
|
|
144
|
+
setShowSuggestions(false);
|
|
145
|
+
}, 150);
|
|
146
|
+
},
|
|
147
|
+
children: item.disease_name
|
|
148
|
+
}, item.id);
|
|
149
|
+
});
|
|
150
|
+
}, [deferredData, dispatch, isStale, setShowSuggestions]);
|
|
151
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
|
|
152
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Dropdown.Header, {
|
|
153
|
+
children: "Diseases"
|
|
154
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
|
|
155
|
+
style: {
|
|
156
|
+
maxHeight: "25vh",
|
|
157
|
+
overflowY: "scroll"
|
|
158
|
+
},
|
|
159
|
+
children: deferredData !== null && deferredData !== void 0 && deferredData.length ? suggestionsList : /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Dropdown.Item, {
|
|
160
|
+
as: "button",
|
|
161
|
+
disabled: true,
|
|
162
|
+
children: !serverError ? isStale || isPending ? "Loading..." : "No items found" : "Failed to fetch data"
|
|
163
|
+
}, "empty")
|
|
164
|
+
})]
|
|
165
|
+
});
|
|
166
|
+
}
|
|
@@ -4,162 +4,52 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.VarNamesList = VarNamesList;
|
|
7
|
-
exports.VarSearchBar = VarSearchBar;
|
|
8
7
|
require("bootstrap/dist/css/bootstrap.min.css");
|
|
9
8
|
var _react = _interopRequireWildcard(require("react"));
|
|
10
9
|
var _lodash = _interopRequireDefault(require("lodash"));
|
|
11
|
-
var _requests = require("../../utils/requests");
|
|
12
10
|
var _DatasetContext = require("../../context/DatasetContext");
|
|
13
11
|
var _constants = require("../../constants/constants");
|
|
14
12
|
var _reactBootstrap = require("react-bootstrap");
|
|
15
|
-
var _LoadingSpinner = require("../../utils/LoadingSpinner");
|
|
16
13
|
var _jsxRuntime = require("react/jsx-runtime");
|
|
17
14
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
18
15
|
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
16
|
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 && Object.prototype.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; }
|
|
20
|
-
function
|
|
17
|
+
function VarNamesList(_ref) {
|
|
18
|
+
var _dataset$selectedVar, _dataset$selectedDise, _dataset$selectedDise2, _dataset$selectedDise3;
|
|
21
19
|
let {
|
|
22
|
-
|
|
23
|
-
|
|
20
|
+
mode = _constants.SELECTION_MODES.SINGLE,
|
|
21
|
+
displayName = "genes"
|
|
24
22
|
} = _ref;
|
|
25
|
-
const [suggestions, setSuggestions] = (0, _react.useState)([]);
|
|
26
|
-
const [showSuggestions, setShowSuggestions] = (0, _react.useState)(false);
|
|
27
|
-
const [text, setText] = (0, _react.useState)("");
|
|
28
|
-
const getSuggestions = (0, _react.useMemo)(() => {
|
|
29
|
-
const filter = text => {
|
|
30
|
-
if (text.length > 0) {
|
|
31
|
-
const regex = new RegExp("^".concat(text), "i");
|
|
32
|
-
const filter = varNames.sort().filter(v => regex.test(v.name));
|
|
33
|
-
setSuggestions(filter);
|
|
34
|
-
setShowSuggestions(true);
|
|
35
|
-
} else {
|
|
36
|
-
setShowSuggestions(false);
|
|
37
|
-
}
|
|
38
|
-
};
|
|
39
|
-
return _lodash.default.debounce(filter, 300);
|
|
40
|
-
}, [varNames]);
|
|
41
|
-
(0, _react.useEffect)(() => {
|
|
42
|
-
getSuggestions(text);
|
|
43
|
-
}, [getSuggestions, text]);
|
|
44
|
-
const suggestionsList = suggestions.map(item => /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Dropdown.Item, {
|
|
45
|
-
as: "button",
|
|
46
|
-
onClick: () => {
|
|
47
|
-
onSelect(item);
|
|
48
|
-
},
|
|
49
|
-
children: item.name
|
|
50
|
-
}, item.name));
|
|
51
|
-
return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
|
|
52
|
-
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Form, {
|
|
53
|
-
onSubmit: e => {
|
|
54
|
-
e.preventDefault();
|
|
55
|
-
},
|
|
56
|
-
children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactBootstrap.FormGroup, {
|
|
57
|
-
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Form.Label, {
|
|
58
|
-
children: "Feature:"
|
|
59
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Form.Control, {
|
|
60
|
-
onFocus: () => {
|
|
61
|
-
setShowSuggestions(text.length > 0);
|
|
62
|
-
},
|
|
63
|
-
onBlur: () => {
|
|
64
|
-
_lodash.default.delay(() => {
|
|
65
|
-
setShowSuggestions(false);
|
|
66
|
-
}, 150);
|
|
67
|
-
},
|
|
68
|
-
type: "text",
|
|
69
|
-
placeholder: "Search for a feature",
|
|
70
|
-
value: text,
|
|
71
|
-
onChange: e => {
|
|
72
|
-
setText(e.target.value);
|
|
73
|
-
}
|
|
74
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Dropdown.Menu, {
|
|
75
|
-
style: {
|
|
76
|
-
width: "90%",
|
|
77
|
-
maxHeight: "25vh",
|
|
78
|
-
overflowY: "scroll"
|
|
79
|
-
},
|
|
80
|
-
show: showSuggestions,
|
|
81
|
-
children: suggestionsList
|
|
82
|
-
})]
|
|
83
|
-
})
|
|
84
|
-
})
|
|
85
|
-
});
|
|
86
|
-
}
|
|
87
|
-
function VarNamesList(_ref2) {
|
|
88
|
-
let {
|
|
89
|
-
mode = _constants.SELECTION_MODES.SINGLE
|
|
90
|
-
} = _ref2;
|
|
91
|
-
const ENDPOINT = "var/names";
|
|
92
23
|
const dataset = (0, _DatasetContext.useDataset)();
|
|
93
24
|
const dispatch = (0, _DatasetContext.useDatasetDispatch)();
|
|
94
|
-
const [
|
|
95
|
-
const [
|
|
96
|
-
const [varButtons, setVarButtons] = (0, _react.useState)(mode ? mode === _constants.SELECTION_MODES.SINGLE ? [dataset.selectVar] : dataset.selectedMultiVar : []);
|
|
97
|
-
const [active, setActive] = (0, _react.useState)(mode === _constants.SELECTION_MODES.SINGLE ? dataset.selectVar : dataset.selectedMultiVar);
|
|
98
|
-
const [params, setParams] = (0, _react.useState)({
|
|
99
|
-
url: dataset.url
|
|
100
|
-
});
|
|
25
|
+
const [varButtons, setVarButtons] = (0, _react.useState)(mode === _constants.SELECTION_MODES.SINGLE ? [dataset.selectedVar] : dataset.selectedMultiVar);
|
|
26
|
+
const [active, setActive] = (0, _react.useState)(mode === _constants.SELECTION_MODES.SINGLE ? (_dataset$selectedVar = dataset.selectedVar) === null || _dataset$selectedVar === void 0 ? void 0 : _dataset$selectedVar.matrix_index : dataset.selectedMultiVar.map(i => i.matrix_index));
|
|
101
27
|
(0, _react.useEffect)(() => {
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
const {
|
|
110
|
-
fetchedData,
|
|
111
|
-
isPending,
|
|
112
|
-
serverError
|
|
113
|
-
} = (0, _requests.useFetch)(ENDPOINT, params, {
|
|
114
|
-
refetchOnMount: false
|
|
115
|
-
});
|
|
116
|
-
const validateSelection = (0, _react.useCallback)((selectedVar, mode) => {
|
|
117
|
-
if (updatedVarNames) {
|
|
118
|
-
if (mode === _constants.SELECTION_MODES.SINGLE) {
|
|
119
|
-
if (selectedVar && !_lodash.default.some(varNames, selectedVar)) {
|
|
120
|
-
setActive(null);
|
|
121
|
-
dispatch({
|
|
122
|
-
type: "varSelected",
|
|
123
|
-
var: null
|
|
124
|
-
});
|
|
125
|
-
}
|
|
126
|
-
} else {
|
|
127
|
-
if (selectedVar.length && !_lodash.default.every(selectedVar, v => _lodash.default.some(varNames, v))) {
|
|
128
|
-
setActive([]);
|
|
129
|
-
dispatch({
|
|
130
|
-
type: "multiVarReset",
|
|
131
|
-
var: []
|
|
132
|
-
});
|
|
28
|
+
if (mode === _constants.SELECTION_MODES.SINGLE) {
|
|
29
|
+
var _dataset$selectedVar2;
|
|
30
|
+
setVarButtons(v => {
|
|
31
|
+
if (dataset.selectedVar) {
|
|
32
|
+
return _lodash.default.unionWith(v, [dataset.selectedVar], _lodash.default.isEqual);
|
|
33
|
+
} else {
|
|
34
|
+
return [];
|
|
133
35
|
}
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
}, [dispatch, varNames, updatedVarNames]);
|
|
137
|
-
(0, _react.useEffect)(() => {
|
|
138
|
-
if (!isPending && !serverError) {
|
|
139
|
-
setVarNames(fetchedData);
|
|
140
|
-
setUpdatedVarNames(true);
|
|
141
|
-
}
|
|
142
|
-
}, [fetchedData, isPending, serverError]);
|
|
143
|
-
(0, _react.useEffect)(() => {
|
|
144
|
-
if (mode === _constants.SELECTION_MODES.SINGLE && dataset.selectedVar) {
|
|
145
|
-
validateSelection(dataset.selectVar, mode);
|
|
146
|
-
setActive(dataset.selectedVar.matrix_index);
|
|
36
|
+
});
|
|
37
|
+
setActive((_dataset$selectedVar2 = dataset.selectedVar) === null || _dataset$selectedVar2 === void 0 ? void 0 : _dataset$selectedVar2.matrix_index);
|
|
147
38
|
}
|
|
148
|
-
}, [mode, dataset.selectedVar
|
|
39
|
+
}, [mode, dataset.selectedVar]);
|
|
149
40
|
(0, _react.useEffect)(() => {
|
|
150
41
|
if (mode === _constants.SELECTION_MODES.MULTIPLE) {
|
|
151
|
-
|
|
42
|
+
setVarButtons(v => {
|
|
43
|
+
if (dataset.selectedMultiVar.length) {
|
|
44
|
+
return _lodash.default.unionWith(v, dataset.selectedMultiVar, _lodash.default.isEqual);
|
|
45
|
+
} else {
|
|
46
|
+
return [];
|
|
47
|
+
}
|
|
48
|
+
});
|
|
152
49
|
setActive(dataset.selectedMultiVar.map(i => i.matrix_index));
|
|
153
50
|
}
|
|
154
|
-
}, [mode, dataset.selectedMultiVar
|
|
155
|
-
const selectVar = item => {
|
|
156
|
-
setVarButtons(() => {
|
|
157
|
-
if (varButtons[0] && varButtons.find(v => v.matrix_index === item.matrix_index)) {
|
|
158
|
-
return varButtons;
|
|
159
|
-
} else {
|
|
160
|
-
return [...varButtons, item];
|
|
161
|
-
}
|
|
162
|
-
});
|
|
51
|
+
}, [mode, dataset.selectedMultiVar]);
|
|
52
|
+
const selectVar = (0, _react.useCallback)(item => {
|
|
163
53
|
if (mode === _constants.SELECTION_MODES.SINGLE) {
|
|
164
54
|
dispatch({
|
|
165
55
|
type: "varSelected",
|
|
@@ -171,26 +61,25 @@ function VarNamesList(_ref2) {
|
|
|
171
61
|
var: item
|
|
172
62
|
});
|
|
173
63
|
}
|
|
174
|
-
};
|
|
175
|
-
const
|
|
176
|
-
return
|
|
64
|
+
}, [dispatch, mode]);
|
|
65
|
+
const makeList = (0, _react.useCallback)(vars => {
|
|
66
|
+
return vars.map(item => {
|
|
177
67
|
if (item && mode === _constants.SELECTION_MODES.SINGLE) {
|
|
178
68
|
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Button, {
|
|
179
69
|
type: "button",
|
|
180
|
-
variant: "outline-primary",
|
|
70
|
+
variant: item.matrix_index !== -1 ? "outline-primary" : "outline-secondary",
|
|
181
71
|
className: "".concat(active === item.matrix_index && "active", " m-1"),
|
|
182
72
|
onClick: () => {
|
|
183
|
-
|
|
184
|
-
type: "varSelected",
|
|
185
|
-
var: item
|
|
186
|
-
});
|
|
73
|
+
selectVar(item);
|
|
187
74
|
},
|
|
75
|
+
disabled: item.matrix_index === -1,
|
|
76
|
+
title: item.matrix_index === -1 ? "Not present in data" : "",
|
|
188
77
|
children: item.name
|
|
189
78
|
}, item.matrix_index);
|
|
190
79
|
} else if (mode === _constants.SELECTION_MODES.MULTIPLE) {
|
|
191
80
|
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Button, {
|
|
192
81
|
type: "button",
|
|
193
|
-
variant: "outline-primary",
|
|
82
|
+
variant: item.matrix_index !== -1 ? "outline-primary" : "outline-secondary",
|
|
194
83
|
className: "".concat(active.includes(item.matrix_index) && "active", " m-1"),
|
|
195
84
|
onClick: () => {
|
|
196
85
|
if (active.includes(item.matrix_index)) {
|
|
@@ -199,38 +88,63 @@ function VarNamesList(_ref2) {
|
|
|
199
88
|
var: item
|
|
200
89
|
});
|
|
201
90
|
} else {
|
|
202
|
-
|
|
203
|
-
type: "multiVarSelected",
|
|
204
|
-
var: item
|
|
205
|
-
});
|
|
91
|
+
selectVar(item);
|
|
206
92
|
}
|
|
207
93
|
},
|
|
94
|
+
disabled: item.matrix_index === -1,
|
|
95
|
+
title: item.matrix_index === -1 ? "Not present in data" : "",
|
|
208
96
|
children: item.name
|
|
209
97
|
}, item.matrix_index);
|
|
210
98
|
} else {
|
|
211
99
|
return null;
|
|
212
100
|
}
|
|
213
101
|
});
|
|
214
|
-
}, [active, dispatch, mode,
|
|
215
|
-
|
|
216
|
-
return
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
102
|
+
}, [active, dispatch, mode, selectVar]);
|
|
103
|
+
const varList = (0, _react.useMemo)(() => {
|
|
104
|
+
return makeList(varButtons);
|
|
105
|
+
}, [makeList, varButtons]);
|
|
106
|
+
const diseaseVarList = (0, _react.useMemo)(() => {
|
|
107
|
+
return makeList(dataset.selectedDisease.genes);
|
|
108
|
+
}, [makeList, dataset.selectedDisease.genes]);
|
|
109
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
|
|
110
|
+
className: "position-relative",
|
|
111
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
|
|
112
|
+
className: "overflow-auto mt-2",
|
|
113
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
|
|
114
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
|
|
115
|
+
className: "d-flex justify-content-between",
|
|
116
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("h5", {
|
|
117
|
+
children: _lodash.default.capitalize(displayName)
|
|
118
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Button, {
|
|
119
|
+
variant: "link",
|
|
120
|
+
onClick: () => {
|
|
121
|
+
dispatch({
|
|
122
|
+
type: mode === _constants.SELECTION_MODES.SINGLE ? "reset.var" : "reset.multiVar"
|
|
123
|
+
});
|
|
124
|
+
},
|
|
125
|
+
children: "clear"
|
|
126
|
+
})]
|
|
127
|
+
}), varList]
|
|
223
128
|
}), /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
|
|
224
|
-
|
|
225
|
-
|
|
129
|
+
children: ((_dataset$selectedDise = dataset.selectedDisease) === null || _dataset$selectedDise === void 0 ? void 0 : _dataset$selectedDise.id) && ((_dataset$selectedDise2 = dataset.selectedDisease) === null || _dataset$selectedDise2 === void 0 || (_dataset$selectedDise2 = _dataset$selectedDise2.genes) === null || _dataset$selectedDise2 === void 0 ? void 0 : _dataset$selectedDise2.length) > 0 && /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
|
|
130
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
|
|
131
|
+
className: "d-flex justify-content-between",
|
|
132
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("h5", {
|
|
133
|
+
children: "Disease genes"
|
|
134
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Button, {
|
|
135
|
+
variant: "link",
|
|
136
|
+
onClick: () => {
|
|
137
|
+
dispatch({
|
|
138
|
+
type: "reset.disease"
|
|
139
|
+
});
|
|
140
|
+
},
|
|
141
|
+
children: "clear"
|
|
142
|
+
})]
|
|
143
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)("p", {
|
|
144
|
+
children: (_dataset$selectedDise3 = dataset.selectedDisease) === null || _dataset$selectedDise3 === void 0 ? void 0 : _dataset$selectedDise3.name
|
|
145
|
+
}), diseaseVarList]
|
|
146
|
+
})
|
|
226
147
|
})]
|
|
227
|
-
})
|
|
228
|
-
}
|
|
229
|
-
return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
|
|
230
|
-
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Alert, {
|
|
231
|
-
variant: "danger",
|
|
232
|
-
children: serverError.message
|
|
233
|
-
})
|
|
234
|
-
});
|
|
235
|
-
}
|
|
148
|
+
})
|
|
149
|
+
});
|
|
236
150
|
}
|
|
@@ -7,6 +7,8 @@ exports.Violin = Violin;
|
|
|
7
7
|
exports.ViolinControls = ViolinControls;
|
|
8
8
|
require("bootstrap/dist/css/bootstrap.min.css");
|
|
9
9
|
var _react = _interopRequireWildcard(require("react"));
|
|
10
|
+
var _reactFontawesome = require("@fortawesome/react-fontawesome");
|
|
11
|
+
var _freeSolidSvgIcons = require("@fortawesome/free-solid-svg-icons");
|
|
10
12
|
var _reactPlotly = _interopRequireDefault(require("react-plotly.js"));
|
|
11
13
|
var _DatasetContext = require("../../context/DatasetContext");
|
|
12
14
|
var _constants = require("../../constants/constants");
|
|
@@ -66,7 +68,8 @@ function Violin(_ref) {
|
|
|
66
68
|
const [params, setParams] = (0, _react.useState)({
|
|
67
69
|
url: dataset.url,
|
|
68
70
|
keys: [],
|
|
69
|
-
scale: dataset.controls.standardScale
|
|
71
|
+
scale: dataset.controls.standardScale,
|
|
72
|
+
varNamesCol: dataset.varNamesCol
|
|
70
73
|
});
|
|
71
74
|
// @TODO: set default scale
|
|
72
75
|
|
|
@@ -81,8 +84,9 @@ function Violin(_ref) {
|
|
|
81
84
|
return {
|
|
82
85
|
...p,
|
|
83
86
|
url: dataset.url,
|
|
84
|
-
keys: dataset.selectedMultiVar.map(i => i.
|
|
85
|
-
scale: dataset.controls.standardScale
|
|
87
|
+
keys: dataset.selectedMultiVar.map(i => i.index),
|
|
88
|
+
scale: dataset.controls.standardScale,
|
|
89
|
+
varNamesCol: dataset.varNamesCol
|
|
86
90
|
};
|
|
87
91
|
});
|
|
88
92
|
} else if (mode === _constants.VIOLIN_MODES.GROUPBY) {
|
|
@@ -95,13 +99,14 @@ function Violin(_ref) {
|
|
|
95
99
|
return {
|
|
96
100
|
...p,
|
|
97
101
|
url: dataset.url,
|
|
98
|
-
keys: dataset.selectedVar.
|
|
102
|
+
keys: dataset.selectedVar.index,
|
|
99
103
|
selectedObs: dataset.selectedObs,
|
|
100
|
-
scale: dataset.controls.standardScale
|
|
104
|
+
scale: dataset.controls.standardScale,
|
|
105
|
+
varNamesCol: dataset.varNamesCol
|
|
101
106
|
};
|
|
102
107
|
});
|
|
103
108
|
}
|
|
104
|
-
}, [dataset.controls.standardScale, dataset.selectedMultiVar, dataset.selectedObs, dataset.selectedVar, dataset.url, mode]);
|
|
109
|
+
}, [dataset.controls.standardScale, dataset.selectedMultiVar, dataset.selectedObs, dataset.selectedVar, dataset.url, dataset.varNamesCol, mode]);
|
|
105
110
|
const {
|
|
106
111
|
fetchedData,
|
|
107
112
|
isPending,
|
|
@@ -129,6 +134,19 @@ function Violin(_ref) {
|
|
|
129
134
|
maxWidth: "100%",
|
|
130
135
|
maxHeight: "100%"
|
|
131
136
|
}
|
|
137
|
+
}), (fetchedData === null || fetchedData === void 0 ? void 0 : fetchedData.resampled) && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactBootstrap.Alert, {
|
|
138
|
+
variant: "warning",
|
|
139
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("b", {
|
|
140
|
+
children: "Warning:"
|
|
141
|
+
}), " For performance reasons this plot was generated with resampled data. It will not be exactly the same as one produced with the entire dataset. \xA0", /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.OverlayTrigger, {
|
|
142
|
+
placement: "top",
|
|
143
|
+
overlay: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Tooltip, {
|
|
144
|
+
children: "Resampled to 100K values following a Monte Carlo style approach to help ensure resampled data is a good representation of the original dataset's distribution."
|
|
145
|
+
}),
|
|
146
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactFontawesome.FontAwesomeIcon, {
|
|
147
|
+
icon: _freeSolidSvgIcons.faCircleInfo
|
|
148
|
+
})
|
|
149
|
+
})]
|
|
132
150
|
})]
|
|
133
151
|
});
|
|
134
152
|
}
|
|
@@ -53,6 +53,7 @@ const persistOptions = {
|
|
|
53
53
|
};
|
|
54
54
|
const initialDataset = {
|
|
55
55
|
obs: {},
|
|
56
|
+
varNamesCol: null,
|
|
56
57
|
selectedObs: null,
|
|
57
58
|
selectedObsm: null,
|
|
58
59
|
selectedVar: null,
|
|
@@ -73,6 +74,12 @@ const initialDataset = {
|
|
|
73
74
|
},
|
|
74
75
|
state: {
|
|
75
76
|
obs: {}
|
|
77
|
+
},
|
|
78
|
+
diseaseDatasets: [],
|
|
79
|
+
selectedDisease: {
|
|
80
|
+
id: null,
|
|
81
|
+
name: null,
|
|
82
|
+
genes: []
|
|
76
83
|
}
|
|
77
84
|
};
|
|
78
85
|
const initializer = initialState => {
|
|
@@ -84,12 +91,13 @@ const initializer = initialState => {
|
|
|
84
91
|
function DatasetProvider(_ref2) {
|
|
85
92
|
let {
|
|
86
93
|
dataset_url,
|
|
94
|
+
dataset_params = null,
|
|
87
95
|
children
|
|
88
96
|
} = _ref2;
|
|
89
|
-
const [dataset, dispatch] = (0, _react.useReducer)(datasetReducer, {
|
|
97
|
+
const [dataset, dispatch] = (0, _react.useReducer)(datasetReducer, _lodash.default.assign(initializer({
|
|
90
98
|
url: dataset_url,
|
|
91
99
|
...initialDataset
|
|
92
|
-
},
|
|
100
|
+
}), dataset_params));
|
|
93
101
|
(0, _react.useEffect)(() => {
|
|
94
102
|
try {
|
|
95
103
|
localStorage.setItem(_constants.LOCAL_STORAGE_KEY, JSON.stringify({
|
|
@@ -123,10 +131,6 @@ function useDatasetDispatch() {
|
|
|
123
131
|
}
|
|
124
132
|
function datasetReducer(dataset, action) {
|
|
125
133
|
switch (action.type) {
|
|
126
|
-
case "setDataset":
|
|
127
|
-
{
|
|
128
|
-
return action.dataset;
|
|
129
|
-
}
|
|
130
134
|
case "set.obs":
|
|
131
135
|
{
|
|
132
136
|
return {
|
|
@@ -157,7 +161,7 @@ function datasetReducer(dataset, action) {
|
|
|
157
161
|
}
|
|
158
162
|
case "multiVarSelected":
|
|
159
163
|
{
|
|
160
|
-
if (dataset.selectedMultiVar.find(i => i
|
|
164
|
+
if (dataset.selectedMultiVar.find(i => _lodash.default.isEqual(i, action.var))) {
|
|
161
165
|
return dataset;
|
|
162
166
|
} else {
|
|
163
167
|
return {
|
|
@@ -170,7 +174,7 @@ function datasetReducer(dataset, action) {
|
|
|
170
174
|
{
|
|
171
175
|
return {
|
|
172
176
|
...dataset,
|
|
173
|
-
selectedMultiVar: dataset.selectedMultiVar.filter(a => a !== action.var)
|
|
177
|
+
selectedMultiVar: dataset.selectedMultiVar.filter(a => a.matrix_index !== action.var.matrix_index)
|
|
174
178
|
};
|
|
175
179
|
}
|
|
176
180
|
case "set.colorEncoding":
|
|
@@ -180,13 +184,52 @@ function datasetReducer(dataset, action) {
|
|
|
180
184
|
colorEncoding: action.value
|
|
181
185
|
};
|
|
182
186
|
}
|
|
183
|
-
case "
|
|
187
|
+
case "reset.multiVar":
|
|
184
188
|
{
|
|
185
189
|
return {
|
|
186
190
|
...dataset,
|
|
187
191
|
selectedMultiVar: []
|
|
188
192
|
};
|
|
189
193
|
}
|
|
194
|
+
case "reset.var":
|
|
195
|
+
{
|
|
196
|
+
return {
|
|
197
|
+
...dataset,
|
|
198
|
+
selectedVar: null
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
case "select.disease":
|
|
202
|
+
{
|
|
203
|
+
return {
|
|
204
|
+
...dataset,
|
|
205
|
+
selectedDisease: {
|
|
206
|
+
id: action.id,
|
|
207
|
+
name: action.name,
|
|
208
|
+
genes: []
|
|
209
|
+
}
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
case "set.disease.genes":
|
|
213
|
+
{
|
|
214
|
+
return {
|
|
215
|
+
...dataset,
|
|
216
|
+
selectedDisease: {
|
|
217
|
+
...dataset.selectedDisease,
|
|
218
|
+
genes: action.genes
|
|
219
|
+
}
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
case "reset.disease":
|
|
223
|
+
{
|
|
224
|
+
return {
|
|
225
|
+
...dataset,
|
|
226
|
+
selectedDisease: {
|
|
227
|
+
id: null,
|
|
228
|
+
name: null,
|
|
229
|
+
genes: []
|
|
230
|
+
}
|
|
231
|
+
};
|
|
232
|
+
}
|
|
190
233
|
case "set.controls.colorScale":
|
|
191
234
|
{
|
|
192
235
|
return {
|
|
@@ -7,20 +7,23 @@ exports.ColorHelper = void 0;
|
|
|
7
7
|
var _chromaJs = _interopRequireDefault(require("chroma-js"));
|
|
8
8
|
var _lodash = _interopRequireDefault(require("lodash"));
|
|
9
9
|
var _constants = require("../constants/constants");
|
|
10
|
-
var _DatasetContext = require("../context/DatasetContext");
|
|
11
10
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
11
|
+
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
12
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : String(i); }
|
|
13
|
+
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); }
|
|
12
14
|
class ColorHelper {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
15
|
+
constructor() {
|
|
16
|
+
_defineProperty(this, "getScale", (colorScale, values) => {
|
|
17
|
+
return _chromaJs.default.scale(_constants.CHROMA_COLORSCALES[colorScale]).domain([_lodash.default.min(values), _lodash.default.max(values)]);
|
|
18
|
+
});
|
|
19
|
+
_defineProperty(this, "getColor", function (colorEncoding, state, value) {
|
|
20
|
+
let scale = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : _chromaJs.default.scale();
|
|
21
|
+
if (colorEncoding === "var") {
|
|
22
|
+
return scale(value).rgb();
|
|
23
|
+
} else if (colorEncoding === "obs") {
|
|
24
|
+
return state !== null && state !== void 0 && state.hasOwnProperty(value) ? state[value]["color"] : null;
|
|
25
|
+
}
|
|
26
|
+
});
|
|
24
27
|
}
|
|
25
28
|
}
|
|
26
29
|
exports.ColorHelper = ColorHelper;
|
package/dist/index.js
CHANGED
|
@@ -111,6 +111,12 @@ Object.defineProperty(exports, "ScatterplotControls", {
|
|
|
111
111
|
return _Scatterplot.ScatterplotControls;
|
|
112
112
|
}
|
|
113
113
|
});
|
|
114
|
+
Object.defineProperty(exports, "SearchBar", {
|
|
115
|
+
enumerable: true,
|
|
116
|
+
get: function () {
|
|
117
|
+
return _SearchBar.SearchBar;
|
|
118
|
+
}
|
|
119
|
+
});
|
|
114
120
|
Object.defineProperty(exports, "VIOLIN_MODES", {
|
|
115
121
|
enumerable: true,
|
|
116
122
|
get: function () {
|
|
@@ -138,6 +144,7 @@ Object.defineProperty(exports, "ViolinControls", {
|
|
|
138
144
|
var _ObsList = require("./components/obs-list/ObsList");
|
|
139
145
|
var _ObsmList = require("./components/obsm-list/ObsmList");
|
|
140
146
|
var _VarList = require("./components/var-list/VarList");
|
|
147
|
+
var _SearchBar = require("./components/search-bar/SearchBar");
|
|
141
148
|
var _Heatmap = require("./components/heatmap/Heatmap");
|
|
142
149
|
var _Dotplot = require("./components/dotplot/Dotplot");
|
|
143
150
|
var _Scatterplot = require("./components/scatterplot/Scatterplot");
|
package/dist/utils/requests.js
CHANGED
|
@@ -11,7 +11,8 @@ var _errors = require("./errors");
|
|
|
11
11
|
async function fetchData(endpoint, params) {
|
|
12
12
|
let signal = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
|
|
13
13
|
let ms = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 300000;
|
|
14
|
-
|
|
14
|
+
let apiUrl = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : null;
|
|
15
|
+
apiUrl = apiUrl || process.env.REACT_APP_API_URL;
|
|
15
16
|
const controller = new AbortController();
|
|
16
17
|
const timeout = setTimeout(() => {
|
|
17
18
|
controller.abort(DOMException.TIMEOUT_ERR);
|
|
@@ -40,6 +41,10 @@ async function fetchData(endpoint, params) {
|
|
|
40
41
|
}
|
|
41
42
|
const useFetch = function (endpoint, params) {
|
|
42
43
|
let opts = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
|
|
44
|
+
let apiUrl = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
|
|
45
|
+
const {
|
|
46
|
+
enabled = true
|
|
47
|
+
} = opts;
|
|
43
48
|
const {
|
|
44
49
|
data: fetchedData,
|
|
45
50
|
isLoading: isPending,
|
|
@@ -50,7 +55,11 @@ const useFetch = function (endpoint, params) {
|
|
|
50
55
|
let {
|
|
51
56
|
signal
|
|
52
57
|
} = _ref;
|
|
53
|
-
|
|
58
|
+
if (enabled) {
|
|
59
|
+
return fetchData(endpoint, params, signal, apiUrl);
|
|
60
|
+
} else {
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
54
63
|
},
|
|
55
64
|
...opts
|
|
56
65
|
});
|
|
@@ -64,6 +73,10 @@ exports.useFetch = useFetch;
|
|
|
64
73
|
const useDebouncedFetch = function (endpoint, params) {
|
|
65
74
|
let delay = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 500;
|
|
66
75
|
let opts = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
|
|
76
|
+
let apiUrl = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : null;
|
|
77
|
+
const {
|
|
78
|
+
enabled = true
|
|
79
|
+
} = opts;
|
|
67
80
|
const debouncedParams = (0, _usehooks.useDebounce)(params, delay);
|
|
68
81
|
const {
|
|
69
82
|
data: fetchedData,
|
|
@@ -75,7 +88,11 @@ const useDebouncedFetch = function (endpoint, params) {
|
|
|
75
88
|
let {
|
|
76
89
|
signal
|
|
77
90
|
} = _ref2;
|
|
78
|
-
|
|
91
|
+
if (enabled) {
|
|
92
|
+
return fetchData(endpoint, debouncedParams, signal, apiUrl);
|
|
93
|
+
} else {
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
79
96
|
},
|
|
80
97
|
...opts
|
|
81
98
|
});
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.useVarSearch = exports.useGetDisease = exports.useDiseaseSearch = void 0;
|
|
7
|
+
var _react = require("react");
|
|
8
|
+
var _DatasetContext = require("../context/DatasetContext");
|
|
9
|
+
var _requests = require("./requests");
|
|
10
|
+
const useDiseaseSearch = () => {
|
|
11
|
+
const ENDPOINT = "diseases";
|
|
12
|
+
const dataset = (0, _DatasetContext.useDataset)();
|
|
13
|
+
const [params, setParams] = (0, _react.useState)({
|
|
14
|
+
url: dataset.url,
|
|
15
|
+
diseaseDatasets: dataset.diseaseDatasets,
|
|
16
|
+
text: ""
|
|
17
|
+
});
|
|
18
|
+
const data = (0, _requests.useFetch)(ENDPOINT, params, {
|
|
19
|
+
enabled: !!params.text.length
|
|
20
|
+
});
|
|
21
|
+
return {
|
|
22
|
+
params,
|
|
23
|
+
setParams,
|
|
24
|
+
data
|
|
25
|
+
};
|
|
26
|
+
};
|
|
27
|
+
exports.useDiseaseSearch = useDiseaseSearch;
|
|
28
|
+
const useVarSearch = () => {
|
|
29
|
+
const ENDPOINT = "var/names";
|
|
30
|
+
const dataset = (0, _DatasetContext.useDataset)();
|
|
31
|
+
const dispatch = (0, _DatasetContext.useDatasetDispatch)();
|
|
32
|
+
const [params, setParams] = (0, _react.useState)({
|
|
33
|
+
url: dataset.url,
|
|
34
|
+
text: ""
|
|
35
|
+
});
|
|
36
|
+
const data = (0, _requests.useFetch)(ENDPOINT, params, {
|
|
37
|
+
enabled: !!params.text.length
|
|
38
|
+
});
|
|
39
|
+
const onSelect = item => {
|
|
40
|
+
dispatch({
|
|
41
|
+
type: "varSelected",
|
|
42
|
+
var: item
|
|
43
|
+
});
|
|
44
|
+
dispatch({
|
|
45
|
+
type: "multiVarSelected",
|
|
46
|
+
var: item
|
|
47
|
+
});
|
|
48
|
+
};
|
|
49
|
+
return {
|
|
50
|
+
params,
|
|
51
|
+
setParams,
|
|
52
|
+
data,
|
|
53
|
+
onSelect
|
|
54
|
+
};
|
|
55
|
+
};
|
|
56
|
+
exports.useVarSearch = useVarSearch;
|
|
57
|
+
const useGetDisease = () => {
|
|
58
|
+
var _dataset$selectedDise, _dataset$selectedDise2, _params$diseaseName;
|
|
59
|
+
const ENDPOINT = "disease/genes";
|
|
60
|
+
const dataset = (0, _DatasetContext.useDataset)();
|
|
61
|
+
const dispatch = (0, _DatasetContext.useDatasetDispatch)();
|
|
62
|
+
const [params, setParams] = (0, _react.useState)({
|
|
63
|
+
url: dataset.url,
|
|
64
|
+
col: dataset.varNamesCol,
|
|
65
|
+
diseaseName: (_dataset$selectedDise = dataset.selectedDisease) === null || _dataset$selectedDise === void 0 ? void 0 : _dataset$selectedDise.name,
|
|
66
|
+
diseaseDatasets: dataset.diseaseDatasets
|
|
67
|
+
});
|
|
68
|
+
(0, _react.useEffect)(() => {
|
|
69
|
+
setParams(p => {
|
|
70
|
+
return {
|
|
71
|
+
...p,
|
|
72
|
+
diseaseName: dataset.selectedDisease.name
|
|
73
|
+
};
|
|
74
|
+
});
|
|
75
|
+
}, [(_dataset$selectedDise2 = dataset.selectedDisease) === null || _dataset$selectedDise2 === void 0 ? void 0 : _dataset$selectedDise2.name]);
|
|
76
|
+
const {
|
|
77
|
+
fetchedData,
|
|
78
|
+
isPending,
|
|
79
|
+
serverError
|
|
80
|
+
} = (0, _requests.useFetch)(ENDPOINT, params, {
|
|
81
|
+
enabled: !!((_params$diseaseName = params.diseaseName) !== null && _params$diseaseName !== void 0 && _params$diseaseName.length)
|
|
82
|
+
});
|
|
83
|
+
(0, _react.useEffect)(() => {
|
|
84
|
+
if (!isPending && !serverError) {
|
|
85
|
+
dispatch({
|
|
86
|
+
type: "set.disease.genes",
|
|
87
|
+
genes: fetchedData
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
}, [dispatch, fetchedData, isPending, serverError]);
|
|
91
|
+
return;
|
|
92
|
+
};
|
|
93
|
+
exports.useGetDisease = useGetDisease;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@haniffalab/cherita-react",
|
|
3
|
-
"version": "0.2.0-dev.2024-
|
|
3
|
+
"version": "0.2.0-dev.2024-05-09.07fb18ed",
|
|
4
4
|
"author": "",
|
|
5
5
|
"license": "",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -78,5 +78,5 @@
|
|
|
78
78
|
"url": "https://github.com/haniffalab/cherita-react/issues"
|
|
79
79
|
},
|
|
80
80
|
"homepage": "https://github.com/haniffalab/cherita-react#readme",
|
|
81
|
-
"prereleaseSha": "
|
|
81
|
+
"prereleaseSha": "07fb18ed8d66be9ecd7817e41b76b1b5cdf3ba7b"
|
|
82
82
|
}
|