@haniffalab/cherita-react 0.2.0-dev.2024-09-26.775b9a06 → 0.2.0-dev.2024-09-26.1ea62883

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.
Files changed (32) hide show
  1. package/dist/App.scss +77 -8
  2. package/dist/components/Offcanvas/index.js +6 -2
  3. package/dist/components/dotplot/Dotplot.js +22 -5
  4. package/dist/components/dotplot/DotplotControls.js +11 -10
  5. package/dist/components/heatmap/Heatmap.js +22 -5
  6. package/dist/components/matrixplot/Matrixplot.js +22 -5
  7. package/dist/components/matrixplot/MatrixplotControls.js +8 -7
  8. package/dist/components/obs-list/ObsItem.js +394 -0
  9. package/dist/components/obs-list/ObsList.js +116 -299
  10. package/dist/components/obs-list/ObsToolbar.js +76 -0
  11. package/dist/components/scatterplot/Legend.js +4 -3
  12. package/dist/components/scatterplot/Scatterplot.js +129 -61
  13. package/dist/components/scatterplot/Toolbox.js +3 -2
  14. package/dist/components/search-bar/SearchBar.js +18 -2
  15. package/dist/components/search-bar/SearchResults.js +8 -8
  16. package/dist/components/var-list/VarItem.js +316 -0
  17. package/dist/components/var-list/VarList.js +167 -149
  18. package/dist/components/var-list/VarSet.js +214 -0
  19. package/dist/components/violin/Violin.js +46 -13
  20. package/dist/components/violin/ViolinControls.js +13 -18
  21. package/dist/constants/constants.js +41 -29
  22. package/dist/context/DatasetContext.js +91 -31
  23. package/dist/context/FilterContext.js +76 -0
  24. package/dist/helpers/map-helper.js +20 -15
  25. package/dist/helpers/zarr-helper.js +35 -13
  26. package/dist/index.js +7 -0
  27. package/dist/utils/VirtualizedList.js +69 -0
  28. package/dist/utils/requests.js +2 -2
  29. package/dist/utils/search.js +3 -56
  30. package/dist/utils/string.js +18 -0
  31. package/package.json +3 -2
  32. package/dist/components/obs-list/ObsValueList.js +0 -101
@@ -0,0 +1,316 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.SingleSelectionItem = SingleSelectionItem;
7
+ exports.VarItem = VarItem;
8
+ var _react = _interopRequireWildcard(require("react"));
9
+ var _freeSolidSvgIcons = require("@fortawesome/free-solid-svg-icons");
10
+ var _reactFontawesome = require("@fortawesome/react-fontawesome");
11
+ var _iconsMaterial = require("@mui/icons-material");
12
+ var _xCharts = require("@mui/x-charts");
13
+ var _colorPalettes = require("@mui/x-charts/colorPalettes");
14
+ var _lodash = _interopRequireDefault(require("lodash"));
15
+ var _reactBootstrap = require("react-bootstrap");
16
+ var _constants = require("../../constants/constants");
17
+ var _DatasetContext = require("../../context/DatasetContext");
18
+ var _FilterContext = require("../../context/FilterContext");
19
+ var _LoadingIndicators = require("../../utils/LoadingIndicators");
20
+ var _requests = require("../../utils/requests");
21
+ var _string = require("../../utils/string");
22
+ var _VirtualizedList = require("../../utils/VirtualizedList");
23
+ var _jsxRuntime = require("react/jsx-runtime");
24
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
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); }
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; }
27
+ function VarHistogram(_ref) {
28
+ var _fetchedData$bin_edge;
29
+ let {
30
+ item
31
+ } = _ref;
32
+ const ENDPOINT = "var/histograms";
33
+ const dataset = (0, _DatasetContext.useDataset)();
34
+ const filteredData = (0, _FilterContext.useFilteredData)();
35
+ const isSliced = dataset.sliceBy.obs || dataset.sliceBy.polygons;
36
+ const [params, setParams] = (0, _react.useState)({
37
+ url: dataset.url,
38
+ var_index: item.matrix_index,
39
+ obs_indices: isSliced && Array.from(filteredData.obsIndices || [])
40
+ });
41
+ (0, _react.useEffect)(() => {
42
+ setParams(p => {
43
+ return {
44
+ ...p,
45
+ obs_indices: isSliced && Array.from(filteredData.obsIndices || [])
46
+ };
47
+ });
48
+ }, [filteredData.obsIndices, isSliced]);
49
+ const {
50
+ fetchedData,
51
+ isPending,
52
+ serverError
53
+ } = (0, _requests.useDebouncedFetch)(ENDPOINT, params, {
54
+ refetchOnMount: false
55
+ });
56
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
57
+ className: "feature-histogram-container",
58
+ children: isPending ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_LoadingIndicators.LoadingLinear, {}) : !serverError && fetchedData ? /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
59
+ className: "feature-histogram m-1",
60
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_xCharts.SparkLineChart, {
61
+ plotType: "bar",
62
+ data: fetchedData.log10,
63
+ margin: {
64
+ top: 0,
65
+ right: 0,
66
+ bottom: 0,
67
+ left: 0
68
+ },
69
+ colors: isSliced ? _colorPalettes.mangoFusionPalette : _colorPalettes.blueberryTwilightPalette,
70
+ showHighlight: true,
71
+ showTooltip: true,
72
+ valueFormatter: (v, _ref2) => {
73
+ let {
74
+ dataIndex
75
+ } = _ref2;
76
+ return "".concat((0, _string.prettyNumerical)(fetchedData.hist[dataIndex]));
77
+ },
78
+ xAxis: {
79
+ data: _lodash.default.range((_fetchedData$bin_edge = fetchedData.bin_edges) === null || _fetchedData$bin_edge === void 0 ? void 0 : _fetchedData$bin_edge.length) || null,
80
+ valueFormatter: v => "Bin [".concat((0, _string.prettyNumerical)(fetchedData.bin_edges[v][0]), ", ").concat((0, _string.prettyNumerical)(fetchedData.bin_edges[v][1])).concat(v === fetchedData.bin_edges.length - 1 ? "]" : ")")
81
+ },
82
+ slotProps: {
83
+ popper: {
84
+ className: "feature-histogram-tooltip"
85
+ }
86
+ }
87
+ })
88
+ }) : null
89
+ });
90
+ }
91
+ function VarDiseaseInfoItem(item) {
92
+ var _item$metadata;
93
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.ListGroup.Item, {
94
+ className: "feature-disease-info",
95
+ children: /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
96
+ children: [item.disease_name, " ", /*#__PURE__*/(0, _jsxRuntime.jsx)("br", {}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Table, {
97
+ striped: true,
98
+ children: /*#__PURE__*/(0, _jsxRuntime.jsxs)("tbody", {
99
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)("tr", {
100
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("td", {
101
+ children: "Confidence"
102
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)("td", {
103
+ children: item.confidence || "unknown"
104
+ })]
105
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)("tr", {
106
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)("td", {
107
+ children: ["Organ", item.organs.length > 1 ? "s" : ""]
108
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)("td", {
109
+ children: item.organs.map(o => o.name).join(", ")
110
+ })]
111
+ }), !!((_item$metadata = item.metadata) !== null && _item$metadata !== void 0 && _item$metadata.length) && item.metadata.map(m => {
112
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)("tr", {
113
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("td", {
114
+ children: m.key
115
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)("td", {
116
+ children: m.value
117
+ })]
118
+ });
119
+ })]
120
+ })
121
+ })]
122
+ })
123
+ });
124
+ }
125
+ function VarDiseaseInfo(_ref3) {
126
+ let {
127
+ data
128
+ } = _ref3;
129
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_jsxRuntime.Fragment, {
130
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.ListGroup, {
131
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_VirtualizedList.VirtualizedList, {
132
+ getDataAtIndex: index => data[index],
133
+ count: data.length,
134
+ estimateSize: 70,
135
+ maxHeight: "40vh",
136
+ ItemComponent: VarDiseaseInfoItem
137
+ })
138
+ })
139
+ });
140
+ }
141
+ function SingleSelectionItem(_ref4) {
142
+ let {
143
+ item,
144
+ isActive,
145
+ selectVar,
146
+ removeVar,
147
+ isDiseaseGene = false,
148
+ showSetColorEncoding = true,
149
+ showRemove = true
150
+ } = _ref4;
151
+ const ENDPOINT = "disease/gene";
152
+ const [openInfo, setOpenInfo] = (0, _react.useState)(false);
153
+ const dataset = (0, _DatasetContext.useDataset)();
154
+ const params = {
155
+ geneName: item.name,
156
+ diseaseDatasets: dataset.diseaseDatasets
157
+ };
158
+ const isNotInData = item.matrix_index === -1;
159
+ const {
160
+ fetchedData,
161
+ isPending,
162
+ serverError
163
+ } = (0, _requests.useFetch)(ENDPOINT, params);
164
+ const hasDiseaseInfo = !isPending && !serverError && !!fetchedData.length;
165
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
166
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
167
+ className: "d-flex justify-content-between ".concat(hasDiseaseInfo ? "cursor-pointer" : ""),
168
+ onClick: () => {
169
+ setOpenInfo(o => !o);
170
+ },
171
+ children: /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
172
+ className: "d-flex justify-content-between align-items-center w-100",
173
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
174
+ children: item.name
175
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
176
+ className: "d-flex align-items-center gap-1",
177
+ children: [hasDiseaseInfo && /*#__PURE__*/(0, _jsxRuntime.jsx)(_iconsMaterial.MoreVert, {}), !isDiseaseGene && /*#__PURE__*/(0, _jsxRuntime.jsx)(VarHistogram, {
178
+ item: item
179
+ }), showSetColorEncoding && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Button, {
180
+ type: "button",
181
+ variant: isActive ? "primary" : isNotInData ? "outline-secondary" : "outline-primary",
182
+ className: "m-0 p-0 px-1",
183
+ onClick: e => {
184
+ e.stopPropagation();
185
+ selectVar();
186
+ },
187
+ disabled: isNotInData,
188
+ title: isNotInData ? "Not present in data" : "Set as color encoding",
189
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactFontawesome.FontAwesomeIcon, {
190
+ icon: _freeSolidSvgIcons.faDroplet
191
+ })
192
+ }, item.matrix_index), (!isDiseaseGene || !showRemove) && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Button, {
193
+ type: "button",
194
+ className: "m-0 p-0 px-1",
195
+ variant: "outline-secondary",
196
+ title: "Remove from list",
197
+ onClick: e => {
198
+ e.stopPropagation();
199
+ removeVar();
200
+ },
201
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactFontawesome.FontAwesomeIcon, {
202
+ icon: _freeSolidSvgIcons.faTrash
203
+ })
204
+ })]
205
+ })]
206
+ })
207
+ }), hasDiseaseInfo && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Collapse, {
208
+ in: openInfo,
209
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
210
+ className: "mt-2",
211
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(VarDiseaseInfo, {
212
+ data: fetchedData
213
+ })
214
+ })
215
+ })]
216
+ });
217
+ }
218
+ function MultipleSelectionItem(_ref5) {
219
+ let {
220
+ item,
221
+ isActive,
222
+ toggleVar
223
+ } = _ref5;
224
+ const isNotInData = item.matrix_index === -1;
225
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_jsxRuntime.Fragment, {
226
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
227
+ className: "d-flex",
228
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
229
+ className: "flex-grow-1",
230
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Button, {
231
+ type: "button",
232
+ variant: isActive ? "primary" : "outline-primary",
233
+ className: "m-0 p-0 px-1",
234
+ onClick: toggleVar,
235
+ disabled: isNotInData,
236
+ title: isNotInData ? "Not present in data" : item.name,
237
+ children: item.name
238
+ }, item.matrix_index)
239
+ })
240
+ })
241
+ });
242
+ }
243
+ function VarItem(_ref6) {
244
+ let {
245
+ item,
246
+ active,
247
+ setVarButtons,
248
+ mode = _constants.SELECTION_MODES.SINGLE,
249
+ isDiseaseGene = false
250
+ } = _ref6;
251
+ const dataset = (0, _DatasetContext.useDataset)();
252
+ const dispatch = (0, _DatasetContext.useDatasetDispatch)();
253
+ const selectVar = () => {
254
+ if (mode === _constants.SELECTION_MODES.SINGLE) {
255
+ dispatch({
256
+ type: "select.var",
257
+ var: item
258
+ });
259
+ dispatch({
260
+ type: "set.colorEncoding",
261
+ value: "var"
262
+ });
263
+ } else if (mode === _constants.SELECTION_MODES.MULTIPLE) {
264
+ dispatch({
265
+ type: "select.multivar",
266
+ var: item
267
+ });
268
+ }
269
+ };
270
+ const removeVar = () => {
271
+ setVarButtons(b => {
272
+ return b.filter(i => i.name !== item.name);
273
+ });
274
+ if (mode === _constants.SELECTION_MODES.SINGLE) {
275
+ if (active === item.matrix_index) {
276
+ dispatch({
277
+ type: "reset.var"
278
+ });
279
+ }
280
+ } else if (mode === _constants.SELECTION_MODES.MULTIPLE) {
281
+ if (active.includes(item.matrix_index)) {
282
+ dispatch({
283
+ type: "deselect.multivar",
284
+ var: item
285
+ });
286
+ }
287
+ }
288
+ };
289
+ const toggleVar = () => {
290
+ if (active.includes(item.matrix_index)) {
291
+ dispatch({
292
+ type: "deselect.multivar",
293
+ var: item
294
+ });
295
+ } else {
296
+ selectVar(item);
297
+ }
298
+ };
299
+ if (item && mode === _constants.SELECTION_MODES.SINGLE) {
300
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(SingleSelectionItem, {
301
+ item: item,
302
+ isActive: dataset.colorEncoding === _constants.COLOR_ENCODINGS.VAR && active === item.matrix_index,
303
+ selectVar: selectVar,
304
+ removeVar: removeVar,
305
+ isDiseaseGene: isDiseaseGene
306
+ });
307
+ } else if (mode === _constants.SELECTION_MODES.MULTIPLE) {
308
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(MultipleSelectionItem, {
309
+ item: item,
310
+ isActive: item.matrix_index !== -1 && _lodash.default.includes(active, item.matrix_index),
311
+ toggleVar: toggleVar
312
+ });
313
+ } else {
314
+ return null;
315
+ }
316
+ }