@haniffalab/cherita-react 1.0.0-dev.2025-03-13.73606a74 → 1.0.0-dev.2025-03-13.274a553c
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 → cjs/components}/full-page/FullPage.js +6 -5
- package/dist/{components → cjs/components}/full-page/FullPagePseudospatial.js +6 -5
- package/dist/{components → cjs/components}/obs-list/ObsItem.js +50 -46
- package/dist/{components → cjs/components}/obs-list/ObsList.js +9 -7
- package/dist/{components → cjs/components}/obs-list/ObsToolbar.js +12 -11
- package/dist/{components → cjs/components}/offcanvas/index.js +24 -20
- package/dist/{components → cjs/components}/pseudospatial/Pseudospatial.js +9 -8
- package/dist/{components → cjs/components}/pseudospatial/PseudospatialToolbar.js +4 -3
- package/dist/{components → cjs/components}/scatterplot/Scatterplot.js +31 -22
- package/dist/{components → cjs/components}/scatterplot/SpatialControls.js +11 -10
- package/dist/{components → cjs/components}/scatterplot/Toolbox.js +6 -5
- package/dist/{components → cjs/components}/search-bar/SearchBar.js +6 -5
- package/dist/{components → cjs/components}/search-bar/SearchResults.js +13 -17
- package/dist/{components → cjs/components}/var-list/VarItem.js +32 -27
- package/dist/{components → cjs/components}/var-list/VarList.js +14 -10
- package/dist/{components → cjs/components}/var-list/VarListToolbar.js +4 -3
- package/dist/{components → cjs/components}/var-list/VarSet.js +21 -18
- package/dist/{components → cjs/components}/violin/Violin.js +4 -3
- package/dist/{context → cjs/context}/DatasetContext.js +11 -9
- package/dist/{context → cjs/context}/FilterContext.js +4 -3
- package/dist/{context → cjs/context}/ZarrDataContext.js +4 -3
- package/dist/{helpers → cjs/helpers}/color-helper.js +12 -11
- package/dist/{helpers → cjs/helpers}/map-helper.js +8 -7
- package/dist/{helpers → cjs/helpers}/zarr-helper.js +25 -15
- package/dist/{utils → cjs/utils}/Histogram.js +12 -8
- package/dist/{utils → cjs/utils}/ImageViewer.js +6 -5
- package/dist/{utils → cjs/utils}/Legend.js +8 -7
- package/dist/{utils → cjs/utils}/LoadingIndicators.js +5 -4
- package/dist/{utils → cjs/utils}/VirtualizedList.js +10 -9
- package/dist/{utils → cjs/utils}/requests.js +33 -21
- package/dist/{utils → cjs/utils}/string.js +9 -4
- package/dist/{utils → cjs/utils}/zarrData.js +12 -4
- package/dist/css/cherita.css +10 -0
- package/dist/css/cherita.css.map +1 -1
- package/dist/esm/components/dotplot/Dotplot.js +135 -0
- package/dist/esm/components/dotplot/DotplotControls.js +148 -0
- package/dist/esm/components/full-page/FullPage.js +134 -0
- package/dist/esm/components/full-page/FullPagePseudospatial.js +151 -0
- package/dist/esm/components/heatmap/Heatmap.js +105 -0
- package/dist/esm/components/heatmap/HeatmapControls.js +23 -0
- package/dist/esm/components/matrixplot/Matrixplot.js +107 -0
- package/dist/esm/components/matrixplot/MatrixplotControls.js +38 -0
- package/dist/esm/components/obs-list/ObsItem.js +477 -0
- package/dist/esm/components/obs-list/ObsList.js +256 -0
- package/dist/esm/components/obs-list/ObsToolbar.js +58 -0
- package/dist/esm/components/obsm-list/ObsmList.js +72 -0
- package/dist/esm/components/offcanvas/index.js +67 -0
- package/dist/esm/components/pseudospatial/Pseudospatial.js +228 -0
- package/dist/esm/components/pseudospatial/PseudospatialToolbar.js +123 -0
- package/dist/esm/components/scatterplot/Scatterplot.js +394 -0
- package/dist/esm/components/scatterplot/ScatterplotControls.js +71 -0
- package/dist/esm/components/scatterplot/SpatialControls.js +140 -0
- package/dist/esm/components/scatterplot/Toolbox.js +25 -0
- package/dist/esm/components/search-bar/SearchBar.js +74 -0
- package/dist/esm/components/search-bar/SearchResults.js +139 -0
- package/dist/esm/components/var-list/VarItem.js +250 -0
- package/dist/esm/components/var-list/VarList.js +267 -0
- package/dist/esm/components/var-list/VarListToolbar.js +84 -0
- package/dist/esm/components/var-list/VarSet.js +193 -0
- package/dist/esm/components/violin/Violin.js +141 -0
- package/dist/esm/components/violin/ViolinControls.js +24 -0
- package/dist/esm/constants/colorscales.js +22 -0
- package/dist/esm/constants/constants.js +84 -0
- package/dist/esm/context/DatasetContext.js +572 -0
- package/dist/esm/context/FilterContext.js +48 -0
- package/dist/esm/context/ZarrDataContext.js +26 -0
- package/dist/esm/helpers/color-helper.js +66 -0
- package/dist/esm/helpers/map-helper.js +53 -0
- package/dist/esm/helpers/zarr-helper.js +129 -0
- package/dist/esm/index.js +22 -0
- package/dist/esm/utils/Filter.js +147 -0
- package/dist/esm/utils/Histogram.js +44 -0
- package/dist/esm/utils/ImageViewer.js +27 -0
- package/dist/esm/utils/Legend.js +58 -0
- package/dist/esm/utils/LoadingIndicators.js +22 -0
- package/dist/esm/utils/VirtualizedList.js +55 -0
- package/dist/esm/utils/errors.js +47 -0
- package/dist/esm/utils/requests.js +116 -0
- package/dist/esm/utils/search.js +39 -0
- package/dist/esm/utils/string.js +59 -0
- package/dist/esm/utils/zarrData.js +102 -0
- package/package.json +16 -5
- package/scss/cherita.scss +10 -0
- package/scss/components/layouts.scss +1 -0
- /package/dist/{components → cjs/components}/dotplot/Dotplot.js +0 -0
- /package/dist/{components → cjs/components}/dotplot/DotplotControls.js +0 -0
- /package/dist/{components → cjs/components}/heatmap/Heatmap.js +0 -0
- /package/dist/{components → cjs/components}/heatmap/HeatmapControls.js +0 -0
- /package/dist/{components → cjs/components}/matrixplot/Matrixplot.js +0 -0
- /package/dist/{components → cjs/components}/matrixplot/MatrixplotControls.js +0 -0
- /package/dist/{components → cjs/components}/obsm-list/ObsmList.js +0 -0
- /package/dist/{components → cjs/components}/scatterplot/ScatterplotControls.js +0 -0
- /package/dist/{components → cjs/components}/violin/ViolinControls.js +0 -0
- /package/dist/{constants → cjs/constants}/colorscales.js +0 -0
- /package/dist/{constants → cjs/constants}/constants.js +0 -0
- /package/dist/{index.js → cjs/index.js} +0 -0
- /package/dist/{utils → cjs/utils}/Filter.js +0 -0
- /package/dist/{utils → cjs/utils}/errors.js +0 -0
- /package/dist/{utils → cjs/utils}/search.js +0 -0
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
|
|
2
|
+
import React, { useCallback, useEffect, useState } from "react";
|
|
3
|
+
import { useVirtualizer } from "@tanstack/react-virtual";
|
|
4
|
+
export function VirtualizedList(_ref) {
|
|
5
|
+
let {
|
|
6
|
+
getDataAtIndex,
|
|
7
|
+
count,
|
|
8
|
+
ItemComponent,
|
|
9
|
+
estimateSize = 45,
|
|
10
|
+
overscan = 25,
|
|
11
|
+
maxHeight = "80vh",
|
|
12
|
+
...props
|
|
13
|
+
} = _ref;
|
|
14
|
+
const [parentNode, setParentNode] = useState(null);
|
|
15
|
+
const itemVirtualizer = useVirtualizer({
|
|
16
|
+
count: count,
|
|
17
|
+
getScrollElement: () => parentNode,
|
|
18
|
+
estimateSize: () => estimateSize,
|
|
19
|
+
overscan: overscan
|
|
20
|
+
});
|
|
21
|
+
const refCallback = useCallback(node => {
|
|
22
|
+
setParentNode(node);
|
|
23
|
+
}, []);
|
|
24
|
+
const virtualItems = itemVirtualizer.getVirtualItems();
|
|
25
|
+
useEffect(() => {
|
|
26
|
+
itemVirtualizer.measure();
|
|
27
|
+
}, [itemVirtualizer, parentNode?.clientHeight, getDataAtIndex]);
|
|
28
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
29
|
+
ref: refCallback,
|
|
30
|
+
style: {
|
|
31
|
+
overflowY: "auto",
|
|
32
|
+
maxHeight: maxHeight
|
|
33
|
+
},
|
|
34
|
+
className: "modern-scrollbars"
|
|
35
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
36
|
+
style: {
|
|
37
|
+
height: `${itemVirtualizer.getTotalSize()}px`,
|
|
38
|
+
width: "100%",
|
|
39
|
+
position: "relative",
|
|
40
|
+
willChange: "transform"
|
|
41
|
+
}
|
|
42
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
43
|
+
style: {
|
|
44
|
+
position: "absolute",
|
|
45
|
+
top: 0,
|
|
46
|
+
left: 0,
|
|
47
|
+
width: "100%",
|
|
48
|
+
transform: `translateY(${virtualItems[0]?.start ?? 0}px)`
|
|
49
|
+
}
|
|
50
|
+
}, virtualItems.map(virtualItem => /*#__PURE__*/React.createElement("div", {
|
|
51
|
+
key: virtualItem.key,
|
|
52
|
+
"data-index": virtualItem.index,
|
|
53
|
+
ref: itemVirtualizer.measureElement
|
|
54
|
+
}, /*#__PURE__*/React.createElement(ItemComponent, _extends({}, getDataAtIndex(virtualItem.index), props)))))));
|
|
55
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
export const parseError = err => {
|
|
2
|
+
if (err === DOMException.TIMEOUT_ERR) {
|
|
3
|
+
return {
|
|
4
|
+
message: "Timeout error",
|
|
5
|
+
name: err
|
|
6
|
+
};
|
|
7
|
+
}
|
|
8
|
+
switch (err?.name) {
|
|
9
|
+
case "TypeError":
|
|
10
|
+
return {
|
|
11
|
+
...err,
|
|
12
|
+
message: "Failed to fetch data from server"
|
|
13
|
+
};
|
|
14
|
+
case "ReadZarrError":
|
|
15
|
+
return {
|
|
16
|
+
...err,
|
|
17
|
+
message: "Failed to read AnnData-Zarr"
|
|
18
|
+
};
|
|
19
|
+
case "InvalidObs":
|
|
20
|
+
return {
|
|
21
|
+
...err,
|
|
22
|
+
message: "Observation not found in dataset"
|
|
23
|
+
};
|
|
24
|
+
case "InvalidVar":
|
|
25
|
+
return {
|
|
26
|
+
...err,
|
|
27
|
+
message: "Feature not found in dataset"
|
|
28
|
+
};
|
|
29
|
+
case "InvalidKey":
|
|
30
|
+
return {
|
|
31
|
+
...err,
|
|
32
|
+
message: "Key not found in datset"
|
|
33
|
+
};
|
|
34
|
+
case "BadRequest":
|
|
35
|
+
return {
|
|
36
|
+
...err,
|
|
37
|
+
message: "Invalid request to server"
|
|
38
|
+
};
|
|
39
|
+
case "InternalServerError":
|
|
40
|
+
return {
|
|
41
|
+
...err,
|
|
42
|
+
message: "Server error"
|
|
43
|
+
};
|
|
44
|
+
default:
|
|
45
|
+
return err;
|
|
46
|
+
}
|
|
47
|
+
};
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { useQuery } from "@tanstack/react-query";
|
|
2
|
+
import { useDebounce } from "@uidotdev/usehooks";
|
|
3
|
+
import { parseError } from "./errors";
|
|
4
|
+
export async function fetchData(endpoint, params) {
|
|
5
|
+
let signal = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
|
|
6
|
+
let ms = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 300000;
|
|
7
|
+
let apiUrl = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : null;
|
|
8
|
+
apiUrl = apiUrl || process.env.REACT_APP_API_URL;
|
|
9
|
+
const controller = new AbortController();
|
|
10
|
+
const timeout = setTimeout(() => {
|
|
11
|
+
controller.abort(DOMException.TIMEOUT_ERR);
|
|
12
|
+
}, ms || 300000);
|
|
13
|
+
if (signal) signal.addEventListener("abort", () => controller.abort());
|
|
14
|
+
const response = await fetch(new URL(endpoint, apiUrl), {
|
|
15
|
+
method: "POST",
|
|
16
|
+
mode: "cors",
|
|
17
|
+
headers: {
|
|
18
|
+
"Content-Type": "application/json",
|
|
19
|
+
Accept: "application/json"
|
|
20
|
+
},
|
|
21
|
+
body: JSON.stringify(params),
|
|
22
|
+
signal: controller.signal
|
|
23
|
+
}).catch(err => {
|
|
24
|
+
// Manual check as fetch returns an AbortError regardless of the reason set to the signal
|
|
25
|
+
if (controller.signal.aborted && controller.signal.reason === DOMException.TIMEOUT_ERR) {
|
|
26
|
+
throw DOMException.TIMEOUT_ERR;
|
|
27
|
+
}
|
|
28
|
+
throw err;
|
|
29
|
+
}).finally(() => clearTimeout(timeout));
|
|
30
|
+
if (!response.ok) {
|
|
31
|
+
throw await response.json();
|
|
32
|
+
}
|
|
33
|
+
return await response.json();
|
|
34
|
+
}
|
|
35
|
+
export const useFetch = function (endpoint, params) {
|
|
36
|
+
let opts = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {
|
|
37
|
+
refetchOnMount: false,
|
|
38
|
+
refetchOnWindowFocus: false
|
|
39
|
+
};
|
|
40
|
+
let apiUrl = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
|
|
41
|
+
const {
|
|
42
|
+
enabled = true
|
|
43
|
+
} = opts;
|
|
44
|
+
const {
|
|
45
|
+
data: fetchedData = null,
|
|
46
|
+
isPending = false,
|
|
47
|
+
error: serverError = null
|
|
48
|
+
} = useQuery({
|
|
49
|
+
queryKey: [endpoint, params],
|
|
50
|
+
queryFn: _ref => {
|
|
51
|
+
let {
|
|
52
|
+
signal
|
|
53
|
+
} = _ref;
|
|
54
|
+
if (enabled) {
|
|
55
|
+
return fetchData(endpoint, params, signal, apiUrl);
|
|
56
|
+
} else {
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
retry: (failureCount, _ref2) => {
|
|
61
|
+
let {
|
|
62
|
+
error
|
|
63
|
+
} = _ref2;
|
|
64
|
+
if ([400, 401, 403, 404, 422].includes(error?.status)) return false;
|
|
65
|
+
return failureCount < 3;
|
|
66
|
+
},
|
|
67
|
+
...opts
|
|
68
|
+
});
|
|
69
|
+
return {
|
|
70
|
+
fetchedData,
|
|
71
|
+
isPending,
|
|
72
|
+
serverError: parseError(serverError)
|
|
73
|
+
};
|
|
74
|
+
};
|
|
75
|
+
export const useDebouncedFetch = function (endpoint, params) {
|
|
76
|
+
let delay = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 500;
|
|
77
|
+
let opts = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {
|
|
78
|
+
refetchOnMount: false,
|
|
79
|
+
refetchOnWindowFocus: false
|
|
80
|
+
};
|
|
81
|
+
let apiUrl = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : null;
|
|
82
|
+
const {
|
|
83
|
+
enabled = true
|
|
84
|
+
} = opts;
|
|
85
|
+
const debouncedParams = useDebounce(params, delay);
|
|
86
|
+
const {
|
|
87
|
+
data: fetchedData = null,
|
|
88
|
+
isPending = false,
|
|
89
|
+
error: serverError = null
|
|
90
|
+
} = useQuery({
|
|
91
|
+
queryKey: [endpoint, debouncedParams],
|
|
92
|
+
queryFn: _ref3 => {
|
|
93
|
+
let {
|
|
94
|
+
signal
|
|
95
|
+
} = _ref3;
|
|
96
|
+
if (enabled) {
|
|
97
|
+
return fetchData(endpoint, debouncedParams, signal, apiUrl);
|
|
98
|
+
} else {
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
},
|
|
102
|
+
retry: (failureCount, _ref4) => {
|
|
103
|
+
let {
|
|
104
|
+
error
|
|
105
|
+
} = _ref4;
|
|
106
|
+
if ([400, 401, 403, 404, 422].includes(error?.status)) return false;
|
|
107
|
+
return failureCount < 3;
|
|
108
|
+
},
|
|
109
|
+
...opts
|
|
110
|
+
});
|
|
111
|
+
return {
|
|
112
|
+
fetchedData,
|
|
113
|
+
isPending,
|
|
114
|
+
serverError: parseError(serverError)
|
|
115
|
+
};
|
|
116
|
+
};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { useState } from "react";
|
|
2
|
+
import { useFetch } from "./requests";
|
|
3
|
+
import { useDataset } from "../context/DatasetContext";
|
|
4
|
+
export const useDiseaseSearch = () => {
|
|
5
|
+
const ENDPOINT = "diseases";
|
|
6
|
+
const dataset = useDataset();
|
|
7
|
+
const [params, setParams] = useState({
|
|
8
|
+
url: dataset.url,
|
|
9
|
+
diseaseDatasets: dataset.diseaseDatasets,
|
|
10
|
+
text: ""
|
|
11
|
+
});
|
|
12
|
+
const data = useFetch(ENDPOINT, params, {
|
|
13
|
+
enabled: !!params.text.length,
|
|
14
|
+
refetchOnMount: true
|
|
15
|
+
});
|
|
16
|
+
return {
|
|
17
|
+
params,
|
|
18
|
+
setParams,
|
|
19
|
+
data
|
|
20
|
+
};
|
|
21
|
+
};
|
|
22
|
+
export const useVarSearch = () => {
|
|
23
|
+
const ENDPOINT = "var/names";
|
|
24
|
+
const dataset = useDataset();
|
|
25
|
+
const [params, setParams] = useState({
|
|
26
|
+
url: dataset.url,
|
|
27
|
+
col: dataset.varNamesCol,
|
|
28
|
+
text: ""
|
|
29
|
+
});
|
|
30
|
+
const data = useFetch(ENDPOINT, params, {
|
|
31
|
+
enabled: !!params.text.length,
|
|
32
|
+
refetchOnMount: true
|
|
33
|
+
});
|
|
34
|
+
return {
|
|
35
|
+
params,
|
|
36
|
+
setParams,
|
|
37
|
+
data
|
|
38
|
+
};
|
|
39
|
+
};
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import numbro from "numbro";
|
|
2
|
+
export const FORMATS = {
|
|
3
|
+
EXPONENTIAL: "exponential",
|
|
4
|
+
ABBREVIATION: "abbreviation",
|
|
5
|
+
THOUSAND: "thousand"
|
|
6
|
+
};
|
|
7
|
+
function formatThousand(n) {
|
|
8
|
+
let precision = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 3;
|
|
9
|
+
return numbro(n).format({
|
|
10
|
+
thousandSeparated: true,
|
|
11
|
+
mantissa: precision,
|
|
12
|
+
trimMantissa: true
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
function formatExponential(n) {
|
|
16
|
+
let precision = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 3;
|
|
17
|
+
return numbro(n).format({
|
|
18
|
+
exponential: true,
|
|
19
|
+
mantissa: precision,
|
|
20
|
+
trimMantissa: true
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
function formatAbbreviation(n) {
|
|
24
|
+
let precision = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 3;
|
|
25
|
+
return numbro(n).format({
|
|
26
|
+
average: true,
|
|
27
|
+
mantissa: precision,
|
|
28
|
+
trimMantissa: true
|
|
29
|
+
}).toUpperCase();
|
|
30
|
+
}
|
|
31
|
+
export function formatNumerical(n) {
|
|
32
|
+
let format = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : FORMATS.THOUSAND;
|
|
33
|
+
let precision = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 3;
|
|
34
|
+
if (n === 0) {
|
|
35
|
+
return "0";
|
|
36
|
+
} else if (!n || n === undefined || isNaN(n)) {
|
|
37
|
+
return "NaN";
|
|
38
|
+
}
|
|
39
|
+
switch (format) {
|
|
40
|
+
case FORMATS.EXPONENTIAL:
|
|
41
|
+
if (n < 1 / 10 ** precision || n >= 1e6) {
|
|
42
|
+
return formatExponential(n, precision);
|
|
43
|
+
} else {
|
|
44
|
+
return formatThousand(n, precision);
|
|
45
|
+
}
|
|
46
|
+
case FORMATS.ABBREVIATION:
|
|
47
|
+
if (n >= 1e6) {
|
|
48
|
+
return formatAbbreviation(n, precision);
|
|
49
|
+
} else {
|
|
50
|
+
return formatThousand(n, precision);
|
|
51
|
+
}
|
|
52
|
+
case FORMATS.THOUSAND:
|
|
53
|
+
default:
|
|
54
|
+
return formatThousand(n, precision);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
export function formatString(s) {
|
|
58
|
+
return s.trim().replace(/_/g, " ");
|
|
59
|
+
}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { useEffect, useState } from "react";
|
|
2
|
+
import _ from "lodash";
|
|
3
|
+
import { OBS_TYPES } from "../constants/constants";
|
|
4
|
+
import { useDataset } from "../context/DatasetContext";
|
|
5
|
+
import { GET_OPTIONS, useZarr, useMultipleZarr } from "../helpers/zarr-helper";
|
|
6
|
+
export const useObsmData = function () {
|
|
7
|
+
let obsm = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
|
|
8
|
+
const dataset = useDataset();
|
|
9
|
+
obsm = obsm || dataset.selectedObsm;
|
|
10
|
+
const [obsmParams, setObsmParams] = useState({
|
|
11
|
+
url: dataset.url,
|
|
12
|
+
path: "obsm/" + obsm
|
|
13
|
+
});
|
|
14
|
+
useEffect(() => {
|
|
15
|
+
setObsmParams({
|
|
16
|
+
url: dataset.url,
|
|
17
|
+
path: "obsm/" + obsm
|
|
18
|
+
});
|
|
19
|
+
}, [dataset.url, obsm]);
|
|
20
|
+
return useZarr(obsmParams, null, GET_OPTIONS, {
|
|
21
|
+
enabled: !!obsm
|
|
22
|
+
});
|
|
23
|
+
};
|
|
24
|
+
const meanData = (_i, data) => {
|
|
25
|
+
return _.zipWith(...data, function () {
|
|
26
|
+
for (var _len = arguments.length, values = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
27
|
+
values[_key] = arguments[_key];
|
|
28
|
+
}
|
|
29
|
+
return _.mean(values);
|
|
30
|
+
});
|
|
31
|
+
};
|
|
32
|
+
export const useXData = function () {
|
|
33
|
+
let agg = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : meanData;
|
|
34
|
+
const dataset = useDataset();
|
|
35
|
+
const [xParams, setXParams] = useState(!dataset.selectedVar ? [] : !dataset.selectedVar?.isSet ? [{
|
|
36
|
+
url: dataset.url,
|
|
37
|
+
path: "X",
|
|
38
|
+
s: [null, dataset.selectedVar?.matrix_index]
|
|
39
|
+
}] : _.map(dataset.selectedVar?.vars, v => {
|
|
40
|
+
return {
|
|
41
|
+
url: dataset.url,
|
|
42
|
+
path: "X",
|
|
43
|
+
s: [null, v.matrix_index]
|
|
44
|
+
};
|
|
45
|
+
}));
|
|
46
|
+
useEffect(() => {
|
|
47
|
+
setXParams(!dataset.selectedVar ? [] : !dataset.selectedVar?.isSet ? [{
|
|
48
|
+
url: dataset.url,
|
|
49
|
+
path: "X",
|
|
50
|
+
s: [null, dataset.selectedVar?.matrix_index]
|
|
51
|
+
}] : _.map(dataset.selectedVar?.vars, v => {
|
|
52
|
+
return {
|
|
53
|
+
url: dataset.url,
|
|
54
|
+
path: "X",
|
|
55
|
+
s: [null, v.matrix_index]
|
|
56
|
+
};
|
|
57
|
+
}));
|
|
58
|
+
}, [dataset.url, dataset.selectedVar]);
|
|
59
|
+
return useMultipleZarr(xParams, GET_OPTIONS, {
|
|
60
|
+
enabled: !!xParams.length
|
|
61
|
+
}, agg);
|
|
62
|
+
};
|
|
63
|
+
export const useObsData = function () {
|
|
64
|
+
let obs = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
|
|
65
|
+
const dataset = useDataset();
|
|
66
|
+
obs = obs || dataset.selectedObs;
|
|
67
|
+
const [obsParams, setObsParams] = useState({
|
|
68
|
+
url: dataset.url,
|
|
69
|
+
path: "obs/" + obs?.name + (obs?.type === OBS_TYPES.CATEGORICAL ? "/codes" : "")
|
|
70
|
+
});
|
|
71
|
+
useEffect(() => {
|
|
72
|
+
setObsParams({
|
|
73
|
+
url: dataset.url,
|
|
74
|
+
path: "obs/" + obs?.name + (obs?.type === OBS_TYPES.CATEGORICAL ? "/codes" : "")
|
|
75
|
+
});
|
|
76
|
+
}, [dataset.url, obs]);
|
|
77
|
+
return useZarr(obsParams, null, GET_OPTIONS, {
|
|
78
|
+
enabled: !!obs
|
|
79
|
+
});
|
|
80
|
+
};
|
|
81
|
+
export const useLabelObsData = () => {
|
|
82
|
+
const dataset = useDataset();
|
|
83
|
+
const [labelObsParams, setLabelObsParams] = useState(_.map(dataset.labelObs, obs => {
|
|
84
|
+
return {
|
|
85
|
+
url: dataset.url,
|
|
86
|
+
path: "obs/" + obs.name + (obs.type === OBS_TYPES.CATEGORICAL ? "/codes" : ""),
|
|
87
|
+
key: obs.name
|
|
88
|
+
};
|
|
89
|
+
}));
|
|
90
|
+
useEffect(() => {
|
|
91
|
+
setLabelObsParams(_.map(dataset.labelObs, obs => {
|
|
92
|
+
return {
|
|
93
|
+
url: dataset.url,
|
|
94
|
+
path: "obs/" + obs.name + (obs.type === OBS_TYPES.CATEGORICAL ? "/codes" : ""),
|
|
95
|
+
key: obs.name
|
|
96
|
+
};
|
|
97
|
+
}));
|
|
98
|
+
}, [dataset.labelObs, dataset.url]);
|
|
99
|
+
return useMultipleZarr(labelObsParams, GET_OPTIONS, {
|
|
100
|
+
enabled: !!labelObsParams.length
|
|
101
|
+
});
|
|
102
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@haniffalab/cherita-react",
|
|
3
|
-
"version": "1.0.0-dev.2025-03-13.
|
|
3
|
+
"version": "1.0.0-dev.2025-03-13.274a553c",
|
|
4
4
|
"author": "Haniffa Lab",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"keywords": [
|
|
@@ -8,14 +8,23 @@
|
|
|
8
8
|
"bioinformatics",
|
|
9
9
|
"visualization"
|
|
10
10
|
],
|
|
11
|
-
"main": "dist/index.js",
|
|
12
|
-
"module": "dist/index.js",
|
|
11
|
+
"main": "dist/cjs/index.js",
|
|
12
|
+
"module": "dist/esm/index.js",
|
|
13
13
|
"style": "dist/css/cherita.css",
|
|
14
14
|
"sass": "scss/cherita.scss",
|
|
15
15
|
"files": [
|
|
16
16
|
"dist",
|
|
17
17
|
"scss"
|
|
18
18
|
],
|
|
19
|
+
"exports": {
|
|
20
|
+
".": {
|
|
21
|
+
"import": "./dist/esm/index.js",
|
|
22
|
+
"require": "./dist/cjs/index.js"
|
|
23
|
+
},
|
|
24
|
+
"./scss/cherita": "./scss/cherita.scss",
|
|
25
|
+
"./scss/*.scss": "./scss/*.scss",
|
|
26
|
+
"./dist/*.css": "./dist/css/*.css"
|
|
27
|
+
},
|
|
19
28
|
"dependencies": {
|
|
20
29
|
"@emotion/react": "^11.11.4",
|
|
21
30
|
"@emotion/styled": "^11.11.5",
|
|
@@ -74,7 +83,9 @@
|
|
|
74
83
|
"stylelint-config-standard-scss": "^13.1.0"
|
|
75
84
|
},
|
|
76
85
|
"scripts": {
|
|
77
|
-
"build:
|
|
86
|
+
"build:esm": "babel src/lib --out-dir dist/esm --copy-files --env-name esm",
|
|
87
|
+
"build:cjs": "babel src/lib --out-dir dist/cjs --copy-files --env-name cjs",
|
|
88
|
+
"build:babel": "npm run build:esm && npm run build:cjs",
|
|
78
89
|
"build:scss": "sass --load-path=node_modules src/scss/cherita-bootstrap.scss dist/css/cherita.css",
|
|
79
90
|
"copy:scss": "cpx 'src/scss/**/*' 'scss'",
|
|
80
91
|
"build": "npm run build:babel && npm run build:scss && npm run copy:scss",
|
|
@@ -113,5 +124,5 @@
|
|
|
113
124
|
"url": "https://github.com/haniffalab/cherita-react/issues"
|
|
114
125
|
},
|
|
115
126
|
"homepage": "https://github.com/haniffalab/cherita-react#readme",
|
|
116
|
-
"prereleaseSha": "
|
|
127
|
+
"prereleaseSha": "274a553cad08168d96337c2e89917876a601a108"
|
|
117
128
|
}
|
package/scss/cherita.scss
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|