@haniffalab/cherita-react 2.0.0 → 2.1.0
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/cjs/components/dotplot/Dotplot.js +4 -5
- package/dist/cjs/components/dotplot/DotplotControls.js +7 -3
- package/dist/cjs/components/heatmap/Heatmap.js +4 -5
- package/dist/cjs/components/icons/HeatmapIcon.js +2 -2
- package/dist/cjs/components/matrixplot/Matrixplot.js +4 -5
- package/dist/cjs/components/obs-list/ObsItem.js +7 -7
- package/dist/cjs/components/offcanvas/OffCanvas.js +7 -4
- package/dist/cjs/components/plot/PlotTypeSelector.js +49 -10
- package/dist/cjs/components/pseudospatial/Pseudospatial.js +8 -5
- package/dist/cjs/components/scatterplot/Scatterplot.js +134 -136
- package/dist/cjs/components/scatterplot/ScatterplotLayer.js +144 -0
- package/dist/cjs/components/scatterplot/SpatialControls.js +7 -4
- package/dist/cjs/components/scatterplot/Toolbox.js +8 -4
- package/dist/cjs/components/search-bar/SearchBar.js +51 -29
- package/dist/cjs/components/search-bar/SearchInfo.js +2 -2
- package/dist/cjs/components/search-bar/SearchResults.js +9 -6
- package/dist/cjs/components/toolbar/Toolbar.js +10 -65
- package/dist/cjs/components/var-list/VarItem.js +4 -6
- package/dist/cjs/components/var-list/VarList.js +17 -9
- package/dist/cjs/components/var-list/VarListToolbar.js +1 -1
- package/dist/cjs/components/var-list/VarSet.js +7 -5
- package/dist/cjs/components/violin/Violin.js +6 -7
- package/dist/cjs/constants/constants.js +6 -3
- package/dist/cjs/context/DatasetContext.js +11 -2
- package/dist/cjs/context/SettingsContext.js +27 -2
- package/dist/cjs/helpers/color-helper.js +17 -12
- package/dist/cjs/index.js +0 -7
- package/dist/cjs/utils/Legend.js +6 -5
- package/dist/cjs/utils/requests.js +2 -2
- package/dist/cjs/views/ObservationFeature/StandardView.js +1 -1
- package/dist/cjs/views/PerturbationMap/ObsExplorer.js +11 -9
- package/dist/cjs/views/PerturbationMap/StandardView.js +2 -1
- package/dist/cjs/workers/scatterplotData.js +16 -0
- package/dist/esm/components/dotplot/Dotplot.js +5 -6
- package/dist/esm/components/dotplot/DotplotControls.js +6 -3
- package/dist/esm/components/heatmap/Heatmap.js +5 -6
- package/dist/esm/components/icons/HeatmapIcon.js +2 -2
- package/dist/esm/components/matrixplot/Matrixplot.js +5 -6
- package/dist/esm/components/obs-list/ObsItem.js +7 -7
- package/dist/esm/components/offcanvas/OffCanvas.js +7 -4
- package/dist/esm/components/plot/PlotTypeSelector.js +49 -10
- package/dist/esm/components/pseudospatial/Pseudospatial.js +8 -5
- package/dist/esm/components/scatterplot/Scatterplot.js +132 -134
- package/dist/esm/components/scatterplot/ScatterplotLayer.js +137 -0
- package/dist/esm/components/scatterplot/SpatialControls.js +7 -4
- package/dist/esm/components/scatterplot/Toolbox.js +8 -4
- package/dist/esm/components/search-bar/SearchBar.js +52 -30
- package/dist/esm/components/search-bar/SearchInfo.js +2 -2
- package/dist/esm/components/search-bar/SearchResults.js +9 -6
- package/dist/esm/components/toolbar/Toolbar.js +9 -63
- package/dist/esm/components/var-list/VarItem.js +4 -6
- package/dist/esm/components/var-list/VarList.js +17 -9
- package/dist/esm/components/var-list/VarListToolbar.js +1 -1
- package/dist/esm/components/var-list/VarSet.js +7 -5
- package/dist/esm/components/violin/Violin.js +7 -8
- package/dist/esm/constants/constants.js +5 -2
- package/dist/esm/context/DatasetContext.js +11 -2
- package/dist/esm/context/SettingsContext.js +27 -2
- package/dist/esm/helpers/color-helper.js +17 -12
- package/dist/esm/index.js +0 -1
- package/dist/esm/utils/Legend.js +6 -5
- package/dist/esm/utils/requests.js +2 -2
- package/dist/esm/views/ObservationFeature/StandardView.js +1 -1
- package/dist/esm/views/PerturbationMap/ObsExplorer.js +11 -9
- package/dist/esm/views/PerturbationMap/StandardView.js +2 -1
- package/dist/esm/workers/scatterplotData.js +10 -0
- package/package.json +6 -3
|
@@ -166,7 +166,7 @@ export function SettingsProvider(_ref2) {
|
|
|
166
166
|
|
|
167
167
|
// If the buster is not set or does not match the current package version,
|
|
168
168
|
// reset localSettings to avoid stale data
|
|
169
|
-
if (!buster || buster !== "2.
|
|
169
|
+
if (!buster || buster !== "2.1.0") {
|
|
170
170
|
localSettings = {};
|
|
171
171
|
}
|
|
172
172
|
const initSettings = useRef(initializer({
|
|
@@ -191,7 +191,7 @@ export function SettingsProvider(_ref2) {
|
|
|
191
191
|
if (canOverrideSettings && settings) {
|
|
192
192
|
try {
|
|
193
193
|
localStorage.setItem(DATASET_STORAGE_KEY, JSON.stringify(_objectSpread({
|
|
194
|
-
buster: "2.
|
|
194
|
+
buster: "2.1.0" || '0.0.0',
|
|
195
195
|
timestamp: Date.now()
|
|
196
196
|
}, _.omit(settings, 'data'))));
|
|
197
197
|
} catch (err) {
|
|
@@ -335,6 +335,31 @@ function settingsReducer(settings, action) {
|
|
|
335
335
|
}));
|
|
336
336
|
}
|
|
337
337
|
}
|
|
338
|
+
case 'select.multivar.batch':
|
|
339
|
+
{
|
|
340
|
+
const newVars = [];
|
|
341
|
+
let newVarData = {};
|
|
342
|
+
_.forEach(action.vars, v => {
|
|
343
|
+
const inMultiVar = settings.selectedMultiVar.some(mv => mv.name === v.name);
|
|
344
|
+
if (!inMultiVar) {
|
|
345
|
+
const {
|
|
346
|
+
settings: varSettings,
|
|
347
|
+
data: varData
|
|
348
|
+
} = splitVar(v);
|
|
349
|
+
newVars.push(varSettings);
|
|
350
|
+
newVarData = _objectSpread(_objectSpread({}, newVarData), varData);
|
|
351
|
+
}
|
|
352
|
+
});
|
|
353
|
+
if (!newVars.length) {
|
|
354
|
+
return validateSettings(_objectSpread({}, settings));
|
|
355
|
+
}
|
|
356
|
+
return validateSettings(_objectSpread(_objectSpread({}, settings), {}, {
|
|
357
|
+
selectedMultiVar: [...settings.selectedMultiVar, ...newVars],
|
|
358
|
+
data: _objectSpread(_objectSpread({}, settings.data), {}, {
|
|
359
|
+
vars: _objectSpread(_objectSpread({}, settings.data.vars), newVarData)
|
|
360
|
+
})
|
|
361
|
+
}));
|
|
362
|
+
}
|
|
338
363
|
case 'deselect.multivar':
|
|
339
364
|
{
|
|
340
365
|
return validateSettings(_objectSpread(_objectSpread({}, settings), {}, {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { useCallback } from 'react';
|
|
1
|
+
import { useCallback, useMemo } from 'react';
|
|
2
2
|
import { COLORSCALES } from '../constants/colorscales';
|
|
3
|
+
import { GRAY, GRAY_MIX, GRAY_ALPHA } from '../constants/constants';
|
|
3
4
|
import { useSettings } from '../context/SettingsContext';
|
|
4
|
-
const GRAY = [214, 212, 212];
|
|
5
5
|
const parseHexColor = color => {
|
|
6
6
|
const r = parseInt(color === null || color === void 0 ? void 0 : color.substring(1, 3), 16);
|
|
7
7
|
const g = parseInt(color === null || color === void 0 ? void 0 : color.substring(3, 5), 16);
|
|
@@ -33,21 +33,25 @@ export const rgbToHex = color => {
|
|
|
33
33
|
const [r, g, b] = color || [0, 0, 0, 0];
|
|
34
34
|
return '#' + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1);
|
|
35
35
|
};
|
|
36
|
-
export const useColor =
|
|
36
|
+
export const useColor = _ref => {
|
|
37
|
+
let {
|
|
38
|
+
isCategorical = false,
|
|
39
|
+
colorscale = null
|
|
40
|
+
} = _ref;
|
|
37
41
|
const settings = useSettings();
|
|
38
|
-
const
|
|
42
|
+
const colormap = useMemo(() => {
|
|
43
|
+
return colorscale || COLORSCALES[isCategorical ? 'Accent' : settings.controls.colorScale];
|
|
44
|
+
}, [colorscale, isCategorical, settings.controls.colorScale]);
|
|
45
|
+
const getColor = useCallback(_ref2 => {
|
|
39
46
|
let {
|
|
40
47
|
value,
|
|
41
|
-
categorical = false,
|
|
42
48
|
grayOut = false,
|
|
43
49
|
grayParams: {
|
|
44
|
-
alpha =
|
|
45
|
-
gray =
|
|
50
|
+
alpha = GRAY_ALPHA,
|
|
51
|
+
gray = GRAY_MIX
|
|
46
52
|
} = {},
|
|
47
|
-
colorEncoding = settings.colorEncoding
|
|
48
|
-
|
|
49
|
-
} = _ref;
|
|
50
|
-
const colormap = colorscale || COLORSCALES[categorical ? 'Accent' : settings.controls.colorScale];
|
|
53
|
+
colorEncoding = settings.colorEncoding
|
|
54
|
+
} = _ref2;
|
|
51
55
|
if (colorEncoding) {
|
|
52
56
|
if (grayOut) {
|
|
53
57
|
// Mix color with gray manually instead of chroma.mix to get better performance with deck.gl
|
|
@@ -59,8 +63,9 @@ export const useColor = () => {
|
|
|
59
63
|
} else {
|
|
60
64
|
return null;
|
|
61
65
|
}
|
|
62
|
-
}, [settings.colorEncoding,
|
|
66
|
+
}, [settings.colorEncoding, colormap]);
|
|
63
67
|
return {
|
|
68
|
+
colormap,
|
|
64
69
|
getColor
|
|
65
70
|
};
|
|
66
71
|
};
|
package/dist/esm/index.js
CHANGED
|
@@ -13,7 +13,6 @@ export { Pseudospatial } from './components/pseudospatial/Pseudospatial';
|
|
|
13
13
|
export { Scatterplot } from './components/scatterplot/Scatterplot';
|
|
14
14
|
export { ScatterplotControls } from './components/scatterplot/ScatterplotControls';
|
|
15
15
|
export { SearchBar } from './components/search-bar/SearchBar';
|
|
16
|
-
export { Toolbar } from './components/toolbar/Toolbar';
|
|
17
16
|
export { VarNamesList } from './components/var-list/VarList';
|
|
18
17
|
export { Violin } from './components/violin/Violin';
|
|
19
18
|
export { ViolinControls } from './components/violin/ViolinControls';
|
package/dist/esm/utils/Legend.js
CHANGED
|
@@ -18,13 +18,14 @@ export function Legend(_ref) {
|
|
|
18
18
|
const settings = useSettings();
|
|
19
19
|
const {
|
|
20
20
|
getColor
|
|
21
|
-
} = useColor(
|
|
21
|
+
} = useColor({
|
|
22
|
+
isCategorical,
|
|
23
|
+
colorscale
|
|
24
|
+
});
|
|
22
25
|
const spanList = useMemo(() => {
|
|
23
26
|
return _.range(100).map(i => {
|
|
24
27
|
var color = rgbToHex(getColor({
|
|
25
|
-
value: i / 100
|
|
26
|
-
categorical: isCategorical,
|
|
27
|
-
colorscale: colorscale
|
|
28
|
+
value: i / 100
|
|
28
29
|
}));
|
|
29
30
|
return /*#__PURE__*/_jsx("span", {
|
|
30
31
|
className: "grad-step",
|
|
@@ -33,7 +34,7 @@ export function Legend(_ref) {
|
|
|
33
34
|
}
|
|
34
35
|
}, i);
|
|
35
36
|
});
|
|
36
|
-
}, [
|
|
37
|
+
}, [getColor]);
|
|
37
38
|
if (settings.colorEncoding && !isCategorical) {
|
|
38
39
|
var _settings$selectedVar, _settings$selectedObs;
|
|
39
40
|
return /*#__PURE__*/_jsx("div", {
|
|
@@ -8,8 +8,8 @@ import { useDebounce } from '@uidotdev/usehooks';
|
|
|
8
8
|
import { parseError } from './errors';
|
|
9
9
|
export async function fetchData(endpoint, params) {
|
|
10
10
|
let signal = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
|
|
11
|
-
let
|
|
12
|
-
let
|
|
11
|
+
let apiUrl = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
|
|
12
|
+
let ms = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 300000;
|
|
13
13
|
apiUrl = apiUrl || process.env.REACT_APP_API_URL;
|
|
14
14
|
const controller = new AbortController();
|
|
15
15
|
const timeout = setTimeout(() => {
|
|
@@ -103,7 +103,7 @@ export function StandardView(_ref) {
|
|
|
103
103
|
default:
|
|
104
104
|
return /*#__PURE__*/_jsx(Scatterplot, _objectSpread({}, commonProps));
|
|
105
105
|
}
|
|
106
|
-
}, [plotType]);
|
|
106
|
+
}, [plotType, props]);
|
|
107
107
|
return /*#__PURE__*/_jsx("div", {
|
|
108
108
|
className: "cherita-app",
|
|
109
109
|
children: /*#__PURE__*/_jsxs(DatasetProvider, _objectSpread(_objectSpread({}, props), {}, {
|
|
@@ -142,7 +142,9 @@ export function ObsExplorer() {
|
|
|
142
142
|
selectedObsIndex
|
|
143
143
|
} = useSettings();
|
|
144
144
|
const {
|
|
145
|
-
obsExplorer = {}
|
|
145
|
+
obsExplorer = {},
|
|
146
|
+
obsLabel,
|
|
147
|
+
valueLabel
|
|
146
148
|
} = useDataset();
|
|
147
149
|
useParquet(); // initialize duckdb instance
|
|
148
150
|
|
|
@@ -153,9 +155,9 @@ export function ObsExplorer() {
|
|
|
153
155
|
serverError
|
|
154
156
|
} = useObsColsData(obsExplorer === null || obsExplorer === void 0 ? void 0 : obsExplorer.obsCols);
|
|
155
157
|
if (selectedObsIndex == null) {
|
|
156
|
-
return /*#__PURE__*/
|
|
158
|
+
return /*#__PURE__*/_jsxs("div", {
|
|
157
159
|
className: "my-4 text-muted",
|
|
158
|
-
children: "Select a point in the scatterplot to view details about the
|
|
160
|
+
children: ["Select a point in the scatterplot or search for ", obsLabel.plural, " to view details about the ", obsLabel.singular, " perturbation."]
|
|
159
161
|
});
|
|
160
162
|
}
|
|
161
163
|
if (isPending) {
|
|
@@ -177,8 +179,8 @@ export function ObsExplorer() {
|
|
|
177
179
|
children: [/*#__PURE__*/_jsx("h2", {
|
|
178
180
|
className: "fw-bold mb-2",
|
|
179
181
|
children: /*#__PURE__*/_jsx(Tooltip, {
|
|
180
|
-
title: /*#__PURE__*/
|
|
181
|
-
children: "This panel shows metadata and predicted downstream effects for the selected
|
|
182
|
+
title: /*#__PURE__*/_jsxs(_Fragment, {
|
|
183
|
+
children: ["This panel shows metadata and predicted downstream effects for the selected ", obsLabel.singular, " perturbation across the atlas."]
|
|
182
184
|
}),
|
|
183
185
|
placement: "right",
|
|
184
186
|
arrow: true,
|
|
@@ -193,8 +195,8 @@ export function ObsExplorer() {
|
|
|
193
195
|
children: [/*#__PURE__*/_jsx("h5", {
|
|
194
196
|
className: "fw-bold mb-2",
|
|
195
197
|
children: /*#__PURE__*/_jsx(Tooltip, {
|
|
196
|
-
title: /*#__PURE__*/
|
|
197
|
-
children: "These values describe how the selected
|
|
198
|
+
title: /*#__PURE__*/_jsxs(_Fragment, {
|
|
199
|
+
children: ["These values describe how the selected ", obsLabel.singular, ' ', "perturbation is annotated in the atlas, including lineage, biological context, and summary scores used in the perturbation landscape."]
|
|
198
200
|
}),
|
|
199
201
|
placement: "right",
|
|
200
202
|
arrow: true,
|
|
@@ -248,8 +250,8 @@ export function ObsExplorer() {
|
|
|
248
250
|
children: [/*#__PURE__*/_jsxs("h5", {
|
|
249
251
|
className: "fw-bold mb-2 d-flex align-items-center justify-content-between",
|
|
250
252
|
children: [/*#__PURE__*/_jsx(Tooltip, {
|
|
251
|
-
title: /*#__PURE__*/
|
|
252
|
-
children: "This table shows
|
|
253
|
+
title: /*#__PURE__*/_jsxs(_Fragment, {
|
|
254
|
+
children: ["This table shows ", obsLabel.plural, " predicted to change", ' ', valueLabel, " in response to the selected perturbation. Results can be sorted and explored to identify affected pathways and regulatory programs."]
|
|
253
255
|
}),
|
|
254
256
|
placement: "right",
|
|
255
257
|
arrow: true,
|
|
@@ -45,7 +45,8 @@ export function StandardView(_ref) {
|
|
|
45
45
|
setShowSearch: setShowObsExplorer,
|
|
46
46
|
setShowControls: setShowControls,
|
|
47
47
|
isFullscreen: true,
|
|
48
|
-
pointInteractionEnabled: true
|
|
48
|
+
pointInteractionEnabled: true,
|
|
49
|
+
isSearchObs: true
|
|
49
50
|
})
|
|
50
51
|
}), /*#__PURE__*/_jsx("div", {
|
|
51
52
|
className: "cherita-app-sidebar p-3",
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
const WORKER_CODE = "\nfunction computeBitmask(indices, length) {\n if (indices === null) return new Uint8Array(length).fill(1);\n const bitmask = new Uint8Array(length);\n for (const idx of indices) {\n bitmask[idx] = 1;\n }\n return bitmask;\n}\n\nself.onmessage = ({ data }) => {\n // compute and transfer only updated data\n const msg = {};\n const transfer = [];\n\n if (data.positions) {\n const positions = new Float32Array(data.positions.flat());\n msg.positions = positions;\n msg.count = data.positions.length;\n transfer.push(positions.buffer);\n }\n\n if (data.values) {\n const values = new Float32Array(data.values);\n msg.values = values;\n transfer.push(values.buffer);\n }\n\n if (data.obsIndices !== undefined && !!data.length) {\n const bitmask = computeBitmask(data.obsIndices, data.length);\n msg.indexEnabledBitmask = bitmask;\n transfer.push(bitmask.buffer);\n }\n\n self.postMessage(msg, transfer);\n};\n";
|
|
2
|
+
export function createScatterplotWorker() {
|
|
3
|
+
const blob = new Blob([WORKER_CODE], {
|
|
4
|
+
type: 'application/javascript'
|
|
5
|
+
});
|
|
6
|
+
const url = URL.createObjectURL(blob);
|
|
7
|
+
const worker = new Worker(url);
|
|
8
|
+
URL.revokeObjectURL(url);
|
|
9
|
+
return worker;
|
|
10
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@haniffalab/cherita-react",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.1.0",
|
|
4
4
|
"author": "Haniffa Lab",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"keywords": [
|
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
"ndarray-unpack": "^1.0.0",
|
|
53
53
|
"nebula.gl": "^1.0.4",
|
|
54
54
|
"numbro": "^2.5.0",
|
|
55
|
-
"plotly.js": "^
|
|
55
|
+
"plotly.js": "^3.4.0",
|
|
56
56
|
"popper.js": "^1.16.1",
|
|
57
57
|
"react-bootstrap": "^2.7.4",
|
|
58
58
|
"react-plotly.js": "^2.6.0",
|
|
@@ -117,7 +117,10 @@
|
|
|
117
117
|
"lint:js": "eslint 'src/**/*.{js,jsx}' --fix",
|
|
118
118
|
"lint": "npm run lint:scss && npm run lint:js",
|
|
119
119
|
"start-demo": "npm run dev --prefix sites/demo",
|
|
120
|
-
"reinstall": "rm -rf node_modules package-lock.json && npm install"
|
|
120
|
+
"reinstall": "rm -rf node_modules package-lock.json && npm install",
|
|
121
|
+
"docs:start": "npm run start --prefix website",
|
|
122
|
+
"docs:build": "npm run build --prefix website",
|
|
123
|
+
"docs:serve": "npm run serve --prefix website"
|
|
121
124
|
},
|
|
122
125
|
"eslintConfig": {
|
|
123
126
|
"extends": [
|