@haniffalab/cherita-react 0.2.0-dev.2024-12-16.f02cfae4 → 0.2.0-dev.2024-12-16.67617f27
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 +6 -1
- package/dist/components/full-page/FullPage.js +31 -1
- package/dist/components/heatmap/Heatmap.js +6 -1
- package/dist/components/matrixplot/Matrixplot.js +6 -1
- package/dist/components/obs-list/ObsItem.js +65 -21
- package/dist/components/obs-list/ObsList.js +19 -3
- package/dist/components/pseudospatial/Pseudospatial.js +5 -1
- package/dist/components/pseudospatial/PseudospatialToolbar.js +3 -1
- package/dist/components/scatterplot/Scatterplot.js +7 -99
- package/dist/components/var-list/VarItem.js +18 -48
- package/dist/components/var-list/VarList.js +4 -2
- package/dist/components/violin/Violin.js +7 -2
- package/dist/css/cherita.css +5 -0
- package/dist/css/cherita.css.map +1 -1
- package/dist/index.js +6 -0
- package/dist/utils/Filter.js +129 -0
- package/dist/utils/Histogram.js +54 -0
- 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
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.useFilter = void 0;
|
|
7
|
+
var _react = require("react");
|
|
8
|
+
var _turf = require("@turf/turf");
|
|
9
|
+
var _lodash = _interopRequireDefault(require("lodash"));
|
|
10
|
+
var _constants = require("../constants/constants");
|
|
11
|
+
var _DatasetContext = require("../context/DatasetContext");
|
|
12
|
+
var _FilterContext = require("../context/FilterContext");
|
|
13
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
14
|
+
const EPSILON = 1e-6;
|
|
15
|
+
|
|
16
|
+
// @TODO: polish hook
|
|
17
|
+
const useFilter = (data, features) => {
|
|
18
|
+
const dataset = (0, _DatasetContext.useDataset)();
|
|
19
|
+
const filterDataDispatch = (0, _FilterContext.useFilteredDataDispatch)();
|
|
20
|
+
const isInBins = (v, binEdges, indices) => {
|
|
21
|
+
const lastEdge = _lodash.default.last(binEdges);
|
|
22
|
+
const allButLastEdges = _lodash.default.initial(binEdges);
|
|
23
|
+
// add epsilon to last edge to include the last value
|
|
24
|
+
const modifiedBinEdges = [...allButLastEdges, [lastEdge[0], lastEdge[1] + EPSILON]];
|
|
25
|
+
const binIndices = _lodash.default.difference(_lodash.default.range(binEdges.length), indices);
|
|
26
|
+
const ranges = _lodash.default.at(modifiedBinEdges, binIndices);
|
|
27
|
+
return _lodash.default.some(ranges, range => _lodash.default.inRange(v, ...range));
|
|
28
|
+
};
|
|
29
|
+
const isCategorical = (0, _react.useMemo)(() => {
|
|
30
|
+
if (dataset.colorEncoding === _constants.COLOR_ENCODINGS.OBS) {
|
|
31
|
+
return dataset.selectedObs?.type === _constants.OBS_TYPES.CATEGORICAL || dataset.selectedObs?.type === _constants.OBS_TYPES.BOOLEAN;
|
|
32
|
+
} else {
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
}, [dataset.colorEncoding, dataset.selectedObs?.type]);
|
|
36
|
+
const isInSlice = (0, _react.useCallback)((index, values, positions) => {
|
|
37
|
+
let inSlice = true;
|
|
38
|
+
if (isCategorical && values) {
|
|
39
|
+
inSlice &= !_lodash.default.includes(dataset.selectedObs?.omit, values[index]);
|
|
40
|
+
} else if ((dataset.sliceBy.obs || dataset.colorEncoding === _constants.COLOR_ENCODINGS.OBS && dataset.selectedObs?.type === _constants.OBS_TYPES.CONTINUOUS) && !!dataset.selectedObs?.omit.length && values) {
|
|
41
|
+
if (dataset.selectedObs.type === _constants.OBS_TYPES.CATEGORICAL) {
|
|
42
|
+
inSlice &= !_lodash.default.includes(dataset.selectedObs.omit, values[index]);
|
|
43
|
+
} else if (dataset.selectedObs.type === _constants.OBS_TYPES.CONTINUOUS) {
|
|
44
|
+
if (isNaN(values[index])) {
|
|
45
|
+
inSlice &= !_lodash.default.includes(dataset.selectedObs.omit, -1);
|
|
46
|
+
} else {
|
|
47
|
+
inSlice &= isInBins(values[index], dataset.selectedObs.bins.binEdges, _lodash.default.without(dataset.selectedObs.omit, -1));
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
if (dataset.sliceBy.polygons && positions) {
|
|
52
|
+
inSlice &= _lodash.default.some(features?.features, (_f, i) => {
|
|
53
|
+
return (0, _turf.booleanPointInPolygon)((0, _turf.point)([positions[index][0], positions[index][1]]), features.features[i]);
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
return inSlice;
|
|
57
|
+
}, [dataset.colorEncoding, dataset.selectedObs?.bins?.binEdges, dataset.selectedObs?.omit, dataset.selectedObs?.type, dataset.sliceBy.obs, dataset.sliceBy.polygons, features?.features, isCategorical]);
|
|
58
|
+
const {
|
|
59
|
+
filteredIndices,
|
|
60
|
+
valueMin,
|
|
61
|
+
valueMax,
|
|
62
|
+
slicedLength
|
|
63
|
+
} = (0, _react.useMemo)(() => {
|
|
64
|
+
if (dataset.colorEncoding === _constants.COLOR_ENCODINGS.VAR) {
|
|
65
|
+
const {
|
|
66
|
+
filtered,
|
|
67
|
+
filteredIndices
|
|
68
|
+
} = _lodash.default.reduce(data.values, (acc, v, i) => {
|
|
69
|
+
if (isInSlice(i, data.sliceValues, data.positions)) {
|
|
70
|
+
acc.filtered.push(v);
|
|
71
|
+
acc.filteredIndices.add(i);
|
|
72
|
+
}
|
|
73
|
+
return acc;
|
|
74
|
+
}, {
|
|
75
|
+
filtered: [],
|
|
76
|
+
filteredIndices: new Set()
|
|
77
|
+
});
|
|
78
|
+
return {
|
|
79
|
+
filteredIndices: filteredIndices,
|
|
80
|
+
valueMin: _lodash.default.min(filtered),
|
|
81
|
+
valueMax: _lodash.default.max(filtered),
|
|
82
|
+
slicedLength: filtered.length
|
|
83
|
+
};
|
|
84
|
+
} else if (dataset.colorEncoding === _constants.COLOR_ENCODINGS.OBS) {
|
|
85
|
+
const isContinuous = dataset.selectedObs?.type === _constants.OBS_TYPES.CONTINUOUS;
|
|
86
|
+
const {
|
|
87
|
+
filtered,
|
|
88
|
+
filteredIndices
|
|
89
|
+
} = _lodash.default.reduce(data.values, (acc, v, i) => {
|
|
90
|
+
if (isInSlice(i, data.values, data.positions)) {
|
|
91
|
+
acc.filtered.push(v);
|
|
92
|
+
acc.filteredIndices.add(i);
|
|
93
|
+
}
|
|
94
|
+
return acc;
|
|
95
|
+
}, {
|
|
96
|
+
filtered: [],
|
|
97
|
+
filteredIndices: new Set()
|
|
98
|
+
});
|
|
99
|
+
return {
|
|
100
|
+
filteredIndices: filteredIndices,
|
|
101
|
+
valueMin: _lodash.default.min(isContinuous ? filtered : data.values),
|
|
102
|
+
valueMax: _lodash.default.max(isContinuous ? filtered : data.values),
|
|
103
|
+
slicedLength: filtered.length
|
|
104
|
+
};
|
|
105
|
+
} else {
|
|
106
|
+
return {
|
|
107
|
+
filteredIndices: null,
|
|
108
|
+
valueMin: _lodash.default.min(data.values),
|
|
109
|
+
valueMax: _lodash.default.max(data.values),
|
|
110
|
+
slicedLength: data.values.length
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
}, [data.positions, data.sliceValues, data.values, dataset.colorEncoding, dataset.selectedObs?.type, isInSlice]);
|
|
114
|
+
|
|
115
|
+
// @TODO: consider moving dispatch outside of hook, only return values
|
|
116
|
+
(0, _react.useEffect)(() => {
|
|
117
|
+
filterDataDispatch({
|
|
118
|
+
type: "set.obs.indices",
|
|
119
|
+
indices: dataset.sliceBy.obs || dataset.sliceBy.polygons ? filteredIndices : null
|
|
120
|
+
});
|
|
121
|
+
}, [dataset.sliceBy.obs, dataset.sliceBy.polygons, filterDataDispatch, filteredIndices]);
|
|
122
|
+
return {
|
|
123
|
+
filteredIndices,
|
|
124
|
+
valueMin,
|
|
125
|
+
valueMax,
|
|
126
|
+
slicedLength
|
|
127
|
+
};
|
|
128
|
+
};
|
|
129
|
+
exports.useFilter = useFilter;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.Histogram = Histogram;
|
|
7
|
+
var _react = _interopRequireDefault(require("react"));
|
|
8
|
+
var _xCharts = require("@mui/x-charts");
|
|
9
|
+
var _lodash = _interopRequireDefault(require("lodash"));
|
|
10
|
+
var _LoadingIndicators = require("./LoadingIndicators");
|
|
11
|
+
var _string = require("./string");
|
|
12
|
+
var _jsxRuntime = require("react/jsx-runtime");
|
|
13
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
14
|
+
function Histogram(_ref) {
|
|
15
|
+
let {
|
|
16
|
+
data,
|
|
17
|
+
isPending,
|
|
18
|
+
altColor = false
|
|
19
|
+
} = _ref;
|
|
20
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
|
|
21
|
+
className: "feature-histogram-container",
|
|
22
|
+
children: isPending ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_LoadingIndicators.LoadingLinear, {}) : data ? /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
|
|
23
|
+
className: "feature-histogram m-1",
|
|
24
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_xCharts.SparkLineChart, {
|
|
25
|
+
plotType: "bar",
|
|
26
|
+
data: data.log10,
|
|
27
|
+
margin: {
|
|
28
|
+
top: 0,
|
|
29
|
+
right: 0,
|
|
30
|
+
bottom: 0,
|
|
31
|
+
left: 0
|
|
32
|
+
},
|
|
33
|
+
colors: altColor ? _xCharts.mangoFusionPalette : _xCharts.blueberryTwilightPalette,
|
|
34
|
+
showHighlight: true,
|
|
35
|
+
showTooltip: true,
|
|
36
|
+
valueFormatter: (v, _ref2) => {
|
|
37
|
+
let {
|
|
38
|
+
dataIndex
|
|
39
|
+
} = _ref2;
|
|
40
|
+
return `${(0, _string.formatNumerical)(data.hist[dataIndex])}`;
|
|
41
|
+
},
|
|
42
|
+
xAxis: {
|
|
43
|
+
data: _lodash.default.range(data.bin_edges?.length) || null,
|
|
44
|
+
valueFormatter: v => `Bin [${(0, _string.formatNumerical)(data.bin_edges[v][0], _string.FORMATS.EXPONENTIAL)}, ${(0, _string.formatNumerical)(data.bin_edges[v][1], _string.FORMATS.EXPONENTIAL)}${v === data.bin_edges.length - 1 ? "]" : ")"}`
|
|
45
|
+
},
|
|
46
|
+
slotProps: {
|
|
47
|
+
popper: {
|
|
48
|
+
className: "feature-histogram-tooltip"
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
})
|
|
52
|
+
}) : null
|
|
53
|
+
});
|
|
54
|
+
}
|
|
@@ -14,7 +14,7 @@ function VirtualizedList(_ref) {
|
|
|
14
14
|
getDataAtIndex,
|
|
15
15
|
count,
|
|
16
16
|
ItemComponent,
|
|
17
|
-
estimateSize =
|
|
17
|
+
estimateSize = 45,
|
|
18
18
|
overscan = 25,
|
|
19
19
|
maxHeight = "80vh",
|
|
20
20
|
...props
|
|
@@ -32,7 +32,7 @@ function VirtualizedList(_ref) {
|
|
|
32
32
|
const virtualItems = itemVirtualizer.getVirtualItems();
|
|
33
33
|
(0, _react.useEffect)(() => {
|
|
34
34
|
itemVirtualizer.measure();
|
|
35
|
-
}, [itemVirtualizer, parentNode?.clientHeight]);
|
|
35
|
+
}, [itemVirtualizer, parentNode?.clientHeight, getDataAtIndex]);
|
|
36
36
|
return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
|
|
37
37
|
ref: refCallback,
|
|
38
38
|
style: {
|
package/dist/utils/requests.js
CHANGED
|
@@ -42,7 +42,10 @@ async function fetchData(endpoint, params) {
|
|
|
42
42
|
return await response.json();
|
|
43
43
|
}
|
|
44
44
|
const useFetch = function (endpoint, params) {
|
|
45
|
-
let opts = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {
|
|
45
|
+
let opts = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {
|
|
46
|
+
refetchOnMount: false,
|
|
47
|
+
refetchOnWindowFocus: false
|
|
48
|
+
};
|
|
46
49
|
let apiUrl = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
|
|
47
50
|
const {
|
|
48
51
|
enabled = true
|
|
@@ -74,7 +77,10 @@ const useFetch = function (endpoint, params) {
|
|
|
74
77
|
exports.useFetch = useFetch;
|
|
75
78
|
const useDebouncedFetch = function (endpoint, params) {
|
|
76
79
|
let delay = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 500;
|
|
77
|
-
let opts = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {
|
|
80
|
+
let opts = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {
|
|
81
|
+
refetchOnMount: false,
|
|
82
|
+
refetchOnWindowFocus: false
|
|
83
|
+
};
|
|
78
84
|
let apiUrl = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : null;
|
|
79
85
|
const {
|
|
80
86
|
enabled = true
|
package/dist/utils/search.js
CHANGED
|
@@ -16,7 +16,8 @@ const useDiseaseSearch = () => {
|
|
|
16
16
|
text: ""
|
|
17
17
|
});
|
|
18
18
|
const data = (0, _requests.useFetch)(ENDPOINT, params, {
|
|
19
|
-
enabled: !!params.text.length
|
|
19
|
+
enabled: !!params.text.length,
|
|
20
|
+
refetchOnMount: true
|
|
20
21
|
});
|
|
21
22
|
return {
|
|
22
23
|
params,
|
|
@@ -34,7 +35,8 @@ const useVarSearch = () => {
|
|
|
34
35
|
text: ""
|
|
35
36
|
});
|
|
36
37
|
const data = (0, _requests.useFetch)(ENDPOINT, params, {
|
|
37
|
-
enabled: !!params.text.length
|
|
38
|
+
enabled: !!params.text.length,
|
|
39
|
+
refetchOnMount: true
|
|
38
40
|
});
|
|
39
41
|
return {
|
|
40
42
|
params,
|
package/dist/utils/string.js
CHANGED
|
@@ -5,6 +5,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.FORMATS = void 0;
|
|
7
7
|
exports.formatNumerical = formatNumerical;
|
|
8
|
+
exports.formatString = formatString;
|
|
8
9
|
var _numbro = _interopRequireDefault(require("numbro"));
|
|
9
10
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
10
11
|
const FORMATS = exports.FORMATS = {
|
|
@@ -61,4 +62,7 @@ function formatNumerical(n) {
|
|
|
61
62
|
default:
|
|
62
63
|
return formatThousand(n, precision);
|
|
63
64
|
}
|
|
65
|
+
}
|
|
66
|
+
function formatString(s) {
|
|
67
|
+
return s.trim().replace(/_/g, " ");
|
|
64
68
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@haniffalab/cherita-react",
|
|
3
|
-
"version": "0.2.0-dev.2024-12-16.
|
|
3
|
+
"version": "0.2.0-dev.2024-12-16.67617f27",
|
|
4
4
|
"author": "",
|
|
5
5
|
"license": "",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -101,5 +101,5 @@
|
|
|
101
101
|
"url": "https://github.com/haniffalab/cherita-react/issues"
|
|
102
102
|
},
|
|
103
103
|
"homepage": "https://github.com/haniffalab/cherita-react#readme",
|
|
104
|
-
"prereleaseSha": "
|
|
104
|
+
"prereleaseSha": "67617f278b24035c633eed30a5b4d0136e3f77bb"
|
|
105
105
|
}
|
package/scss/cherita.scss
CHANGED
|
@@ -128,6 +128,10 @@
|
|
|
128
128
|
background-color: #cce3ed;
|
|
129
129
|
}
|
|
130
130
|
|
|
131
|
+
.obs-item {
|
|
132
|
+
box-sizing: border-box;
|
|
133
|
+
}
|
|
134
|
+
|
|
131
135
|
.obs-value-list-check {
|
|
132
136
|
padding-right: 1rem;
|
|
133
137
|
word-break: auto-phrase;
|
|
@@ -268,6 +272,7 @@
|
|
|
268
272
|
@extend .col-xxl-6;
|
|
269
273
|
|
|
270
274
|
position: relative;
|
|
275
|
+
max-height: 100%;
|
|
271
276
|
}
|
|
272
277
|
|
|
273
278
|
.cherita-app-obs {
|