@haniffalab/cherita-react 0.2.0-dev.2024-12-16.f02cfae4 → 0.2.0-dev.2024-12-16.6be54149
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/dotplot/Dotplot.js +8 -1
- package/dist/components/full-page/FullPage.js +31 -1
- package/dist/components/heatmap/Heatmap.js +8 -1
- package/dist/components/matrixplot/Matrixplot.js +8 -1
- package/dist/components/obs-list/ObsItem.js +69 -21
- package/dist/components/obs-list/ObsList.js +19 -3
- package/dist/components/pseudospatial/Pseudospatial.js +9 -2
- package/dist/components/pseudospatial/PseudospatialToolbar.js +3 -1
- package/dist/components/scatterplot/Scatterplot.js +26 -108
- package/dist/components/var-list/VarItem.js +24 -50
- package/dist/components/var-list/VarList.js +5 -2
- package/dist/components/violin/Violin.js +9 -2
- package/dist/context/DatasetContext.js +16 -2
- package/dist/context/FilterContext.js +10 -25
- package/dist/context/ZarrDataContext.js +37 -0
- package/dist/css/cherita.css +5 -0
- package/dist/css/cherita.css.map +1 -1
- package/dist/helpers/zarr-helper.js +36 -18
- package/dist/index.js +6 -0
- package/dist/utils/Filter.js +155 -0
- package/dist/utils/Histogram.js +54 -0
- package/dist/utils/Legend.js +3 -2
- package/dist/utils/VirtualizedList.js +2 -2
- package/dist/utils/requests.js +8 -2
- package/dist/utils/search.js +4 -2
- package/dist/utils/string.js +4 -0
- package/package.json +2 -2
- package/scss/cherita.scss +5 -0
|
@@ -9,6 +9,7 @@ var _lodash = _interopRequireDefault(require("lodash"));
|
|
|
9
9
|
var _reactBootstrap = require("react-bootstrap");
|
|
10
10
|
var _reactPlotly = _interopRequireDefault(require("react-plotly.js"));
|
|
11
11
|
var _DatasetContext = require("../../context/DatasetContext");
|
|
12
|
+
var _FilterContext = require("../../context/FilterContext");
|
|
12
13
|
var _LoadingIndicators = require("../../utils/LoadingIndicators");
|
|
13
14
|
var _requests = require("../../utils/requests");
|
|
14
15
|
var _jsxRuntime = require("react/jsx-runtime");
|
|
@@ -18,6 +19,10 @@ function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e;
|
|
|
18
19
|
function Dotplot() {
|
|
19
20
|
const ENDPOINT = "dotplot";
|
|
20
21
|
const dataset = (0, _DatasetContext.useDataset)();
|
|
22
|
+
const {
|
|
23
|
+
obsIndices,
|
|
24
|
+
isSliced
|
|
25
|
+
} = (0, _FilterContext.useFilteredData)();
|
|
21
26
|
const dispatch = (0, _DatasetContext.useDatasetDispatch)();
|
|
22
27
|
const colorscale = (0, _react.useRef)(dataset.controls.colorScale);
|
|
23
28
|
const [data, setData] = (0, _react.useState)([]);
|
|
@@ -31,6 +36,7 @@ function Dotplot() {
|
|
|
31
36
|
name: i.name,
|
|
32
37
|
indices: i.vars.map(v => v.index)
|
|
33
38
|
} : i.index),
|
|
39
|
+
obsIndices: isSliced ? [...(obsIndices || [])] : null,
|
|
34
40
|
standardScale: dataset.controls.standardScale,
|
|
35
41
|
meanOnlyExpressed: dataset.controls.meanOnlyExpressed,
|
|
36
42
|
expressionCutoff: dataset.controls.expressionCutoff,
|
|
@@ -54,13 +60,14 @@ function Dotplot() {
|
|
|
54
60
|
name: i.name,
|
|
55
61
|
indices: i.vars.map(v => v.index)
|
|
56
62
|
} : i.index),
|
|
63
|
+
obsIndices: isSliced ? [...(obsIndices || [])] : null,
|
|
57
64
|
standardScale: dataset.controls.standardScale,
|
|
58
65
|
meanOnlyExpressed: dataset.controls.meanOnlyExpressed,
|
|
59
66
|
expressionCutoff: dataset.controls.expressionCutoff,
|
|
60
67
|
varNamesCol: dataset.varNamesCol
|
|
61
68
|
};
|
|
62
69
|
});
|
|
63
|
-
}, [dataset.url, dataset.selectedObs, dataset.selectedMultiVar, dataset.controls.standardScale, dataset.controls.meanOnlyExpressed, dataset.controls.expressionCutoff, dataset.varNamesCol]);
|
|
70
|
+
}, [dataset.url, dataset.selectedObs, dataset.selectedMultiVar, dataset.controls.standardScale, dataset.controls.meanOnlyExpressed, dataset.controls.expressionCutoff, dataset.varNamesCol, isSliced, obsIndices]);
|
|
64
71
|
const updateColorscale = (0, _react.useCallback)(colorscale => {
|
|
65
72
|
setLayout(l => {
|
|
66
73
|
return {
|
|
@@ -4,12 +4,16 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.FullPage = FullPage;
|
|
7
|
+
exports.FullPagePlots = FullPagePlots;
|
|
7
8
|
exports.FullPagePseudospatial = FullPagePseudospatial;
|
|
8
9
|
exports.FullPageScatterplot = FullPageScatterplot;
|
|
9
10
|
var _react = _interopRequireWildcard(require("react"));
|
|
10
11
|
var _reactBootstrap = require("react-bootstrap");
|
|
11
12
|
var _constants = require("../../constants/constants");
|
|
12
13
|
var _DatasetContext = require("../../context/DatasetContext");
|
|
14
|
+
var _Dotplot = require("../dotplot/Dotplot");
|
|
15
|
+
var _Heatmap = require("../heatmap/Heatmap");
|
|
16
|
+
var _Matrixplot = require("../matrixplot/Matrixplot");
|
|
13
17
|
var _ObsList = require("../obs-list/ObsList");
|
|
14
18
|
var _offcanvas = require("../offcanvas");
|
|
15
19
|
var _Pseudospatial = require("../pseudospatial/Pseudospatial");
|
|
@@ -17,12 +21,14 @@ var _Scatterplot = require("../scatterplot/Scatterplot");
|
|
|
17
21
|
var _ScatterplotControls = require("../scatterplot/ScatterplotControls");
|
|
18
22
|
var _SearchBar = require("../search-bar/SearchBar");
|
|
19
23
|
var _VarList = require("../var-list/VarList");
|
|
24
|
+
var _Violin = require("../violin/Violin");
|
|
20
25
|
var _jsxRuntime = require("react/jsx-runtime");
|
|
21
26
|
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); }
|
|
22
27
|
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
|
|
23
28
|
function FullPage(_ref) {
|
|
24
29
|
let {
|
|
25
30
|
children,
|
|
31
|
+
varMode = _constants.SELECTION_MODES.SINGLE,
|
|
26
32
|
...props
|
|
27
33
|
} = _ref;
|
|
28
34
|
const targetRef = (0, _react.useRef)();
|
|
@@ -111,7 +117,7 @@ function FullPage(_ref) {
|
|
|
111
117
|
searchDiseases: true,
|
|
112
118
|
searchVar: true
|
|
113
119
|
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_VarList.VarNamesList, {
|
|
114
|
-
mode:
|
|
120
|
+
mode: varMode
|
|
115
121
|
})]
|
|
116
122
|
})
|
|
117
123
|
})
|
|
@@ -174,4 +180,28 @@ function FullPagePseudospatial(props) {
|
|
|
174
180
|
})
|
|
175
181
|
})
|
|
176
182
|
});
|
|
183
|
+
}
|
|
184
|
+
function FullPagePlots(props) {
|
|
185
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(FullPage, {
|
|
186
|
+
...props,
|
|
187
|
+
varMode: _constants.SELECTION_MODES.MULTIPLE,
|
|
188
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
|
|
189
|
+
className: "container-fluid w-100 h-100 d-flex flex-column overflow-y-auto",
|
|
190
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
|
|
191
|
+
className: "row flex-grow-1",
|
|
192
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Heatmap.Heatmap, {})
|
|
193
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
|
|
194
|
+
className: "row flex-grow-1",
|
|
195
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Matrixplot.Matrixplot, {})
|
|
196
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
|
|
197
|
+
className: "row flex-grow-1",
|
|
198
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Dotplot.Dotplot, {})
|
|
199
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
|
|
200
|
+
className: "row flex-grow-1",
|
|
201
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Violin.Violin, {
|
|
202
|
+
mode: _constants.VIOLIN_MODES.GROUPBY
|
|
203
|
+
})
|
|
204
|
+
})]
|
|
205
|
+
})
|
|
206
|
+
});
|
|
177
207
|
}
|
|
@@ -9,6 +9,7 @@ var _lodash = _interopRequireDefault(require("lodash"));
|
|
|
9
9
|
var _reactBootstrap = require("react-bootstrap");
|
|
10
10
|
var _reactPlotly = _interopRequireDefault(require("react-plotly.js"));
|
|
11
11
|
var _DatasetContext = require("../../context/DatasetContext");
|
|
12
|
+
var _FilterContext = require("../../context/FilterContext");
|
|
12
13
|
var _LoadingIndicators = require("../../utils/LoadingIndicators");
|
|
13
14
|
var _requests = require("../../utils/requests");
|
|
14
15
|
var _jsxRuntime = require("react/jsx-runtime");
|
|
@@ -18,6 +19,10 @@ function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e;
|
|
|
18
19
|
function Heatmap() {
|
|
19
20
|
const ENDPOINT = "heatmap";
|
|
20
21
|
const dataset = (0, _DatasetContext.useDataset)();
|
|
22
|
+
const {
|
|
23
|
+
obsIndices,
|
|
24
|
+
isSliced
|
|
25
|
+
} = (0, _FilterContext.useFilteredData)();
|
|
21
26
|
const colorscale = (0, _react.useRef)(dataset.controls.colorScale);
|
|
22
27
|
const [data, setData] = (0, _react.useState)([]);
|
|
23
28
|
const [layout, setLayout] = (0, _react.useState)({});
|
|
@@ -30,6 +35,7 @@ function Heatmap() {
|
|
|
30
35
|
name: i.name,
|
|
31
36
|
indices: i.vars.map(v => v.index)
|
|
32
37
|
} : i.index),
|
|
38
|
+
obsIndices: isSliced ? [...(obsIndices || [])] : null,
|
|
33
39
|
varNamesCol: dataset.varNamesCol
|
|
34
40
|
});
|
|
35
41
|
(0, _react.useEffect)(() => {
|
|
@@ -48,10 +54,11 @@ function Heatmap() {
|
|
|
48
54
|
name: i.name,
|
|
49
55
|
indices: i.vars.map(v => v.index)
|
|
50
56
|
} : i.index),
|
|
57
|
+
obsIndices: isSliced ? [...(obsIndices || [])] : null,
|
|
51
58
|
varNamesCol: dataset.varNamesCol
|
|
52
59
|
};
|
|
53
60
|
});
|
|
54
|
-
}, [dataset.selectedMultiVar, dataset.selectedObs, dataset.url, dataset.varNamesCol]);
|
|
61
|
+
}, [dataset.selectedMultiVar, dataset.selectedObs, dataset.url, dataset.varNamesCol, obsIndices, isSliced]);
|
|
55
62
|
const updateColorscale = (0, _react.useCallback)(colorscale => {
|
|
56
63
|
setLayout(l => {
|
|
57
64
|
return {
|
|
@@ -9,6 +9,7 @@ var _lodash = _interopRequireDefault(require("lodash"));
|
|
|
9
9
|
var _reactBootstrap = require("react-bootstrap");
|
|
10
10
|
var _reactPlotly = _interopRequireDefault(require("react-plotly.js"));
|
|
11
11
|
var _DatasetContext = require("../../context/DatasetContext");
|
|
12
|
+
var _FilterContext = require("../../context/FilterContext");
|
|
12
13
|
var _LoadingIndicators = require("../../utils/LoadingIndicators");
|
|
13
14
|
var _requests = require("../../utils/requests");
|
|
14
15
|
var _jsxRuntime = require("react/jsx-runtime");
|
|
@@ -18,6 +19,10 @@ function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e;
|
|
|
18
19
|
function Matrixplot() {
|
|
19
20
|
const ENDPOINT = "matrixplot";
|
|
20
21
|
const dataset = (0, _DatasetContext.useDataset)();
|
|
22
|
+
const {
|
|
23
|
+
obsIndices,
|
|
24
|
+
isSliced
|
|
25
|
+
} = (0, _FilterContext.useFilteredData)();
|
|
21
26
|
const colorscale = (0, _react.useRef)(dataset.controls.colorScale);
|
|
22
27
|
const [data, setData] = (0, _react.useState)([]);
|
|
23
28
|
const [layout, setLayout] = (0, _react.useState)({});
|
|
@@ -30,6 +35,7 @@ function Matrixplot() {
|
|
|
30
35
|
name: i.name,
|
|
31
36
|
indices: i.vars.map(v => v.index)
|
|
32
37
|
} : i.index),
|
|
38
|
+
obsIndices: isSliced ? [...(obsIndices || [])] : null,
|
|
33
39
|
standardScale: dataset.controls.standardScale,
|
|
34
40
|
varNamesCol: dataset.varNamesCol
|
|
35
41
|
});
|
|
@@ -49,11 +55,12 @@ function Matrixplot() {
|
|
|
49
55
|
name: i.name,
|
|
50
56
|
indices: i.vars.map(v => v.index)
|
|
51
57
|
} : i.index),
|
|
58
|
+
obsIndices: isSliced ? [...(obsIndices || [])] : null,
|
|
52
59
|
standardScale: dataset.controls.standardScale,
|
|
53
60
|
varNamesCol: dataset.varNamesCol
|
|
54
61
|
};
|
|
55
62
|
});
|
|
56
|
-
}, [dataset.controls.standardScale, dataset.selectedMultiVar, dataset.selectedObs, dataset.url, dataset.varNamesCol]);
|
|
63
|
+
}, [dataset.controls.standardScale, dataset.selectedMultiVar, dataset.selectedObs, dataset.url, dataset.varNamesCol, obsIndices, isSliced]);
|
|
57
64
|
const updateColorscale = (0, _react.useCallback)(colorscale => {
|
|
58
65
|
setLayout(l => {
|
|
59
66
|
return {
|
|
@@ -11,8 +11,11 @@ var _xCharts = require("@mui/x-charts");
|
|
|
11
11
|
var _lodash = _interopRequireDefault(require("lodash"));
|
|
12
12
|
var _reactBootstrap = require("react-bootstrap");
|
|
13
13
|
var _ObsToolbar = require("./ObsToolbar");
|
|
14
|
+
var _constants = require("../../constants/constants");
|
|
14
15
|
var _DatasetContext = require("../../context/DatasetContext");
|
|
16
|
+
var _FilterContext = require("../../context/FilterContext");
|
|
15
17
|
var _colorHelper = require("../../helpers/color-helper");
|
|
18
|
+
var _Histogram = require("../../utils/Histogram");
|
|
16
19
|
var _LoadingIndicators = require("../../utils/LoadingIndicators");
|
|
17
20
|
var _requests = require("../../utils/requests");
|
|
18
21
|
var _string = require("../../utils/string");
|
|
@@ -22,8 +25,7 @@ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e
|
|
|
22
25
|
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); }
|
|
23
26
|
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
|
|
24
27
|
const N_BINS = 5;
|
|
25
|
-
function binContinuous(data) {
|
|
26
|
-
let nBins = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : N_BINS;
|
|
28
|
+
function binContinuous(data, nBins) {
|
|
27
29
|
const binSize = (data.max - data.min) * (1 / nBins);
|
|
28
30
|
const thresholds = _lodash.default.range(nBins + 1).map(b => {
|
|
29
31
|
return data.min + binSize * b;
|
|
@@ -40,21 +42,44 @@ function binContinuous(data) {
|
|
|
40
42
|
bins: bins
|
|
41
43
|
};
|
|
42
44
|
}
|
|
43
|
-
function binDiscrete(data) {
|
|
44
|
-
let nBins = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : N_BINS;
|
|
45
|
-
const binSize = _lodash.default.round(data.n_values * (1 / nBins));
|
|
46
|
-
const bins = {
|
|
47
|
-
nBins: nBins,
|
|
48
|
-
binSize: binSize
|
|
49
|
-
};
|
|
50
|
-
return {
|
|
51
|
-
...data,
|
|
52
|
-
bins: bins
|
|
53
|
-
};
|
|
54
|
-
}
|
|
55
45
|
function getContinuousLabel(code, binEdges) {
|
|
56
46
|
return `[ ${(0, _string.formatNumerical)(binEdges[code][0])}, ${(0, _string.formatNumerical)(binEdges[code][1], _string.FORMATS.EXPONENTIAL)}${code === binEdges.length - 1 ? " ]" : " )"}`;
|
|
57
47
|
}
|
|
48
|
+
const useObsHistogram = obs => {
|
|
49
|
+
const ENDPOINT = "obs/histograms";
|
|
50
|
+
const dataset = (0, _DatasetContext.useDataset)();
|
|
51
|
+
const {
|
|
52
|
+
obsIndices,
|
|
53
|
+
isSliced
|
|
54
|
+
} = (0, _FilterContext.useFilteredData)();
|
|
55
|
+
const [params, setParams] = (0, _react.useState)({
|
|
56
|
+
url: dataset.url,
|
|
57
|
+
obsCol: _lodash.default.omit(obs, "omit"),
|
|
58
|
+
// avoid re-rendering when toggling unselected obs
|
|
59
|
+
varKey: dataset.selectedVar?.isSet ? {
|
|
60
|
+
name: dataset.selectedVar?.name,
|
|
61
|
+
indices: dataset.selectedVar?.vars.map(v => v.index)
|
|
62
|
+
} : dataset.selectedVar?.index,
|
|
63
|
+
obsIndices: isSliced ? [...(obsIndices || [])] : null
|
|
64
|
+
});
|
|
65
|
+
(0, _react.useEffect)(() => {
|
|
66
|
+
setParams(p => {
|
|
67
|
+
return {
|
|
68
|
+
...p,
|
|
69
|
+
obsCol: _lodash.default.omit(obs, "omit"),
|
|
70
|
+
varKey: dataset.selectedVar?.isSet ? {
|
|
71
|
+
name: dataset.selectedVar?.name,
|
|
72
|
+
indices: dataset.selectedVar?.vars.map(v => v.index)
|
|
73
|
+
} : dataset.selectedVar?.index,
|
|
74
|
+
obsIndices: isSliced ? [...(obsIndices || [])] : null
|
|
75
|
+
};
|
|
76
|
+
});
|
|
77
|
+
}, [dataset.selectedVar?.index, dataset.selectedVar?.isSet, dataset.selectedVar?.name, dataset.selectedVar?.vars, obsIndices, isSliced, obs]);
|
|
78
|
+
return (0, _requests.useFetch)(ENDPOINT, params, {
|
|
79
|
+
enabled: !!dataset.selectedVar && dataset.colorEncoding === _constants.COLOR_ENCODINGS.VAR,
|
|
80
|
+
refetchOnMount: false
|
|
81
|
+
});
|
|
82
|
+
};
|
|
58
83
|
function CategoricalItem(_ref) {
|
|
59
84
|
let {
|
|
60
85
|
value,
|
|
@@ -66,12 +91,18 @@ function CategoricalItem(_ref) {
|
|
|
66
91
|
min,
|
|
67
92
|
max,
|
|
68
93
|
onChange,
|
|
94
|
+
histogramData = {
|
|
95
|
+
data: null,
|
|
96
|
+
isPending: false,
|
|
97
|
+
altColor: false
|
|
98
|
+
},
|
|
69
99
|
showColor = true
|
|
70
100
|
} = _ref;
|
|
71
101
|
const {
|
|
72
102
|
getColor
|
|
73
103
|
} = (0, _colorHelper.useColor)();
|
|
74
104
|
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.ListGroup.Item, {
|
|
105
|
+
className: "obs-item",
|
|
75
106
|
children: /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
|
|
76
107
|
className: "d-flex align-items-center",
|
|
77
108
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
|
|
@@ -85,7 +116,11 @@ function CategoricalItem(_ref) {
|
|
|
85
116
|
})
|
|
86
117
|
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
|
|
87
118
|
className: "d-flex align-items-center",
|
|
88
|
-
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(
|
|
119
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_Histogram.Histogram, {
|
|
120
|
+
data: histogramData.data,
|
|
121
|
+
isPending: histogramData.isPending,
|
|
122
|
+
altColor: histogramData.altColor
|
|
123
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
|
|
89
124
|
className: "pl-1 m-0",
|
|
90
125
|
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Tooltip, {
|
|
91
126
|
title: `${(0, _string.formatNumerical)(pct, _string.FORMATS.EXPONENTIAL)}%`,
|
|
@@ -115,7 +150,7 @@ function CategoricalItem(_ref) {
|
|
|
115
150
|
})]
|
|
116
151
|
})
|
|
117
152
|
})
|
|
118
|
-
}), showColor
|
|
153
|
+
}), showColor ? /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
|
|
119
154
|
className: "pl-1",
|
|
120
155
|
children: /*#__PURE__*/(0, _jsxRuntime.jsx)("svg", {
|
|
121
156
|
xmlns: "http://www.w3.org/2000/svg",
|
|
@@ -139,7 +174,7 @@ function CategoricalItem(_ref) {
|
|
|
139
174
|
})})`
|
|
140
175
|
})
|
|
141
176
|
})
|
|
142
|
-
})]
|
|
177
|
+
}) : null]
|
|
143
178
|
})]
|
|
144
179
|
})
|
|
145
180
|
}, value);
|
|
@@ -156,10 +191,14 @@ function CategoricalObs(_ref2) {
|
|
|
156
191
|
showColor = true
|
|
157
192
|
} = _ref2;
|
|
158
193
|
const dataset = (0, _DatasetContext.useDataset)();
|
|
194
|
+
const {
|
|
195
|
+
isSliced
|
|
196
|
+
} = (0, _FilterContext.useFilteredData)();
|
|
159
197
|
const dispatch = (0, _DatasetContext.useDatasetDispatch)();
|
|
160
198
|
const totalCounts = _lodash.default.sum(_lodash.default.values(obs.value_counts));
|
|
161
199
|
const min = _lodash.default.min(_lodash.default.values(obs.codes));
|
|
162
200
|
const max = _lodash.default.max(_lodash.default.values(obs.codes));
|
|
201
|
+
const obsHistograms = useObsHistogram(obs);
|
|
163
202
|
(0, _react.useEffect)(() => {
|
|
164
203
|
if (dataset.selectedObs?.name === obs.name) {
|
|
165
204
|
const selectedObsData = _lodash.default.omit(dataset.selectedObs, ["omit"]);
|
|
@@ -178,16 +217,25 @@ function CategoricalObs(_ref2) {
|
|
|
178
217
|
}
|
|
179
218
|
}
|
|
180
219
|
}, [dataset.selectedObs, dispatch, obs, obs.name, updateObs]);
|
|
181
|
-
const getDataAtIndex = index => {
|
|
220
|
+
const getDataAtIndex = (0, _react.useCallback)(index => {
|
|
182
221
|
return {
|
|
183
222
|
value: obs.values[index],
|
|
184
223
|
code: obs.codes[obs.values[index]],
|
|
185
224
|
value_counts: obs.value_counts[obs.values[index]],
|
|
186
225
|
pct: obs.value_counts[obs.values[index]] / totalCounts * 100,
|
|
187
226
|
isOmitted: _lodash.default.includes(obs.omit, obs.codes[obs.values[index]]),
|
|
188
|
-
label: obs.values[index]
|
|
227
|
+
label: obs.values[index],
|
|
228
|
+
histogramData: dataset.colorEncoding === _constants.COLOR_ENCODINGS.VAR ? {
|
|
229
|
+
data: obsHistograms.fetchedData?.[obs.values[index]],
|
|
230
|
+
isPending: obsHistograms.isPending,
|
|
231
|
+
altColor: isSliced
|
|
232
|
+
} : {
|
|
233
|
+
data: null,
|
|
234
|
+
isPending: false
|
|
235
|
+
}
|
|
189
236
|
};
|
|
190
|
-
};
|
|
237
|
+
}, [dataset.colorEncoding, isSliced, obs.codes, obs.omit, obs.value_counts, obs.values, obsHistograms.fetchedData, obsHistograms.isPending, totalCounts]);
|
|
238
|
+
showColor &= dataset.colorEncoding === _constants.COLOR_ENCODINGS.OBS;
|
|
191
239
|
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactBootstrap.ListGroup, {
|
|
192
240
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.ListGroup.Item, {
|
|
193
241
|
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_ObsToolbar.ObsToolbar, {
|
|
@@ -312,7 +360,7 @@ function ContinuousObs(_ref4) {
|
|
|
312
360
|
const ENDPOINT = "obs/bins";
|
|
313
361
|
const dataset = (0, _DatasetContext.useDataset)();
|
|
314
362
|
const dispatch = (0, _DatasetContext.useDatasetDispatch)();
|
|
315
|
-
const binnedObs = binContinuous(obs);
|
|
363
|
+
const binnedObs = binContinuous(obs, _lodash.default.min([N_BINS, obs.n_unique]));
|
|
316
364
|
const params = {
|
|
317
365
|
url: dataset.url,
|
|
318
366
|
obsCol: binnedObs.name,
|
|
@@ -25,6 +25,9 @@ function ObsColsList(_ref) {
|
|
|
25
25
|
const dispatch = (0, _DatasetContext.useDatasetDispatch)();
|
|
26
26
|
const [obsCols, setObsCols] = (0, _react.useState)(null);
|
|
27
27
|
const [active, setActive] = (0, _react.useState)(dataset.selectedObs?.name);
|
|
28
|
+
const [expandedItems, setExpandedItems] = (0, _react.useState)(active ? {
|
|
29
|
+
[active]: true
|
|
30
|
+
} : {});
|
|
28
31
|
const [params, setParams] = (0, _react.useState)({
|
|
29
32
|
url: dataset.url
|
|
30
33
|
});
|
|
@@ -79,6 +82,18 @@ function ObsColsList(_ref) {
|
|
|
79
82
|
};
|
|
80
83
|
});
|
|
81
84
|
};
|
|
85
|
+
const handleAccordionToggle = itemName => {
|
|
86
|
+
_lodash.default.delay(
|
|
87
|
+
// to avoid contents of accordion disappearing while closing
|
|
88
|
+
() => {
|
|
89
|
+
setExpandedItems(prev => {
|
|
90
|
+
return {
|
|
91
|
+
...prev,
|
|
92
|
+
[itemName]: !prev[itemName]
|
|
93
|
+
};
|
|
94
|
+
});
|
|
95
|
+
}, expandedItems[itemName] ? 250 : 0);
|
|
96
|
+
};
|
|
82
97
|
const toggleAll = item => {
|
|
83
98
|
const omit = item.omit.length ? [] : _lodash.default.map(item.values, v => item.codes[v]);
|
|
84
99
|
setObsCols(o => {
|
|
@@ -168,9 +183,10 @@ function ObsColsList(_ref) {
|
|
|
168
183
|
eventKey: item.name,
|
|
169
184
|
className: active === item.name && dataset.colorEncoding === _constants.COLOR_ENCODINGS.OBS && "cherita-accordion-active",
|
|
170
185
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Accordion.Header, {
|
|
186
|
+
onClick: () => handleAccordionToggle(item.name),
|
|
171
187
|
children: item.name
|
|
172
188
|
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Accordion.Body, {
|
|
173
|
-
children: item.type === _constants.OBS_TYPES.CATEGORICAL || item.type === _constants.OBS_TYPES.BOOLEAN ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_ObsItem.CategoricalObs, {
|
|
189
|
+
children: expandedItems[item.name] && (item.type === _constants.OBS_TYPES.CATEGORICAL || item.type === _constants.OBS_TYPES.BOOLEAN ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_ObsItem.CategoricalObs, {
|
|
174
190
|
obs: item,
|
|
175
191
|
updateObs: updateObs,
|
|
176
192
|
toggleAll: () => toggleAll(item),
|
|
@@ -187,7 +203,7 @@ function ObsColsList(_ref) {
|
|
|
187
203
|
toggleLabel: () => toggleLabel(item),
|
|
188
204
|
toggleSlice: () => toggleSlice(item),
|
|
189
205
|
toggleColor: () => toggleColor(item)
|
|
190
|
-
}, item.name)
|
|
206
|
+
}, item.name))
|
|
191
207
|
})]
|
|
192
208
|
}, item.name);
|
|
193
209
|
});
|
|
@@ -198,7 +214,7 @@ function ObsColsList(_ref) {
|
|
|
198
214
|
className: "list-group overflow-auto h-100",
|
|
199
215
|
children: [isPending && /*#__PURE__*/(0, _jsxRuntime.jsx)(_LoadingIndicators.LoadingSpinner, {}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Accordion, {
|
|
200
216
|
flush: true,
|
|
201
|
-
defaultActiveKey: active,
|
|
217
|
+
defaultActiveKey: [active],
|
|
202
218
|
alwaysOpen: true,
|
|
203
219
|
children: obsList
|
|
204
220
|
})]
|
|
@@ -12,6 +12,7 @@ var _reactPlotly = _interopRequireDefault(require("react-plotly.js"));
|
|
|
12
12
|
var _PseudospatialToolbar = require("./PseudospatialToolbar");
|
|
13
13
|
var _constants = require("../../constants/constants");
|
|
14
14
|
var _DatasetContext = require("../../context/DatasetContext");
|
|
15
|
+
var _FilterContext = require("../../context/FilterContext");
|
|
15
16
|
var _colorHelper = require("../../helpers/color-helper");
|
|
16
17
|
var _ImageViewer = require("../../utils/ImageViewer");
|
|
17
18
|
var _Legend = require("../../utils/Legend");
|
|
@@ -24,16 +25,21 @@ function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e;
|
|
|
24
25
|
function usePseudospatialData(plotType) {
|
|
25
26
|
const ENDPOINT = "pseudospatial";
|
|
26
27
|
const dataset = (0, _DatasetContext.useDataset)();
|
|
28
|
+
const {
|
|
29
|
+
obsIndices,
|
|
30
|
+
isSliced
|
|
31
|
+
} = (0, _FilterContext.useFilteredData)();
|
|
27
32
|
const baseParams = (0, _react.useMemo)(() => {
|
|
28
33
|
return {
|
|
29
34
|
url: dataset.url,
|
|
30
35
|
maskSet: dataset.pseudospatial.maskSet,
|
|
31
36
|
maskValues: dataset.pseudospatial.maskValues,
|
|
37
|
+
obsIndices: isSliced ? [...(obsIndices || [])] : null,
|
|
32
38
|
varNamesCol: dataset.varNamesCol,
|
|
33
39
|
showColorbar: false,
|
|
34
40
|
format: "json"
|
|
35
41
|
};
|
|
36
|
-
}, [dataset.url, dataset.pseudospatial.maskSet, dataset.pseudospatial.maskValues, dataset.varNamesCol]);
|
|
42
|
+
}, [dataset.url, dataset.pseudospatial.maskSet, dataset.pseudospatial.maskValues, dataset.varNamesCol, isSliced, obsIndices]);
|
|
37
43
|
const getPlotParams = (0, _react.useCallback)(() => {
|
|
38
44
|
if (plotType === _constants.PSEUDOSPATIAL_PLOT_TYPES.GENE) {
|
|
39
45
|
return {
|
|
@@ -187,7 +193,8 @@ function Pseudospatial(_ref) {
|
|
|
187
193
|
}
|
|
188
194
|
}), hasSelections && showLegend && /*#__PURE__*/(0, _jsxRuntime.jsx)(_Legend.Legend, {
|
|
189
195
|
min: layout?.coloraxis?.cmin,
|
|
190
|
-
max: layout?.coloraxis?.cmax
|
|
196
|
+
max: layout?.coloraxis?.cmax,
|
|
197
|
+
addText: plotType === _constants.PSEUDOSPATIAL_PLOT_TYPES.GENE ? " - Mean expression" : plotType === _constants.PSEUDOSPATIAL_PLOT_TYPES.CATEGORICAL ? " - %" : plotType === _constants.PSEUDOSPATIAL_PLOT_TYPES.CONTINUOUS ? " - Mean value" : ""
|
|
191
198
|
})]
|
|
192
199
|
})]
|
|
193
200
|
});
|
|
@@ -59,7 +59,9 @@ function MaskSet() {
|
|
|
59
59
|
fetchedData,
|
|
60
60
|
isPending,
|
|
61
61
|
serverError
|
|
62
|
-
} = (0, _requests.useFetch)(ENDPOINT, params
|
|
62
|
+
} = (0, _requests.useFetch)(ENDPOINT, params, {
|
|
63
|
+
refetchOnMount: false
|
|
64
|
+
});
|
|
63
65
|
(0, _react.useEffect)(() => {
|
|
64
66
|
if (!isPending && !serverError) {
|
|
65
67
|
setMaskSets(fetchedData);
|