@haniffalab/cherita-react 1.3.0 → 1.3.1-dev.2025-10-29.def77f5f
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/README.md +1 -1
- package/dist/cjs/components/controls/Controls.js +38 -30
- package/dist/cjs/components/dotplot/Dotplot.js +85 -57
- package/dist/cjs/components/dotplot/DotplotControls.js +103 -83
- package/dist/cjs/components/full-page/FullPage.js +167 -114
- package/dist/cjs/components/full-page/PlotAlert.js +45 -0
- package/dist/cjs/components/full-page/PlotTypeSelector.js +102 -0
- package/dist/cjs/components/heatmap/Heatmap.js +83 -53
- package/dist/cjs/components/heatmap/HeatmapControls.js +6 -3
- package/dist/cjs/components/icons/DotPlotIcon.js +64 -0
- package/dist/cjs/components/icons/HeatmapIcon.js +45 -0
- package/dist/cjs/components/icons/MatrixPlotIcon.1.js +57 -0
- package/dist/cjs/components/icons/MatrixPlotIcon.js +59 -0
- package/dist/cjs/components/icons/ScatterplotIcon.1.js +164 -0
- package/dist/cjs/components/icons/ScatterplotIcon.js +144 -0
- package/dist/cjs/components/icons/ViolinPlotIcon.js +42 -0
- package/dist/cjs/components/matrixplot/Matrixplot.js +83 -54
- package/dist/cjs/components/matrixplot/MatrixplotControls.js +8 -5
- package/dist/cjs/components/obs-list/ObsItem.js +305 -216
- package/dist/cjs/components/obs-list/ObsList.js +164 -128
- package/dist/cjs/components/obs-list/ObsToolbar.js +2 -3
- package/dist/cjs/components/obsm-list/ObsmList.js +67 -28
- package/dist/cjs/components/offcanvas/index.js +62 -27
- package/dist/cjs/components/pseudospatial/Pseudospatial.js +132 -76
- package/dist/cjs/components/pseudospatial/PseudospatialToolbar.js +122 -74
- package/dist/cjs/components/scatterplot/Scatterplot.js +223 -175
- package/dist/cjs/components/scatterplot/ScatterplotControls.js +45 -31
- package/dist/cjs/components/scatterplot/SpatialControls.js +143 -116
- package/dist/cjs/components/scatterplot/Toolbox.js +41 -30
- package/dist/cjs/components/search-bar/SearchBar.js +176 -120
- package/dist/cjs/components/search-bar/SearchInfo.js +79 -85
- package/dist/cjs/components/search-bar/SearchResults.js +93 -71
- package/dist/cjs/components/toolbar/Toolbar.js +111 -0
- package/dist/cjs/components/var-list/VarItem.js +131 -103
- package/dist/cjs/components/var-list/VarList.js +96 -74
- package/dist/cjs/components/var-list/VarListToolbar.js +59 -54
- package/dist/cjs/components/var-list/VarSet.js +126 -108
- package/dist/cjs/components/violin/Violin.js +124 -81
- package/dist/cjs/components/violin/ViolinControls.js +8 -5
- package/dist/cjs/constants/colorscales.js +19 -19
- package/dist/cjs/constants/constants.js +54 -39
- package/dist/cjs/context/DatasetContext.js +27 -17
- package/dist/cjs/context/FilterContext.js +11 -9
- package/dist/cjs/context/SettingsContext.js +339 -125
- package/dist/cjs/context/ZarrDataContext.js +6 -5
- package/dist/cjs/helpers/color-helper.js +2 -2
- package/dist/cjs/helpers/map-helper.js +2 -1
- package/dist/cjs/helpers/zarr-helper.js +3 -3
- package/dist/cjs/index.js +15 -21
- package/dist/cjs/utils/Filter.js +16 -11
- package/dist/cjs/utils/Histogram.js +35 -33
- package/dist/cjs/utils/ImageViewer.js +11 -8
- package/dist/cjs/utils/Legend.js +37 -30
- package/dist/cjs/utils/LoadingIndicators.js +15 -13
- package/dist/cjs/utils/Resolver.js +213 -0
- package/dist/cjs/utils/Skeleton.js +10 -10
- package/dist/cjs/utils/StyledTooltip.js +44 -0
- package/dist/cjs/utils/VirtualizedList.js +36 -29
- package/dist/cjs/utils/errors.js +15 -15
- package/dist/cjs/utils/requests.js +21 -9
- package/dist/cjs/utils/search.js +4 -4
- package/dist/cjs/utils/string.js +6 -6
- package/dist/cjs/utils/zarrData.js +20 -21
- package/dist/css/cherita.css +188 -65
- package/dist/css/cherita.css.map +1 -1
- package/dist/esm/components/controls/Controls.js +43 -35
- package/dist/esm/components/dotplot/Dotplot.js +93 -64
- package/dist/esm/components/dotplot/DotplotControls.js +106 -85
- package/dist/esm/components/full-page/FullPage.js +180 -124
- package/dist/esm/components/full-page/PlotAlert.js +39 -0
- package/dist/esm/components/full-page/PlotTypeSelector.js +95 -0
- package/dist/esm/components/heatmap/Heatmap.js +91 -60
- package/dist/esm/components/heatmap/HeatmapControls.js +8 -4
- package/dist/esm/components/icons/DotPlotIcon.js +58 -0
- package/dist/esm/components/icons/HeatmapIcon.js +39 -0
- package/dist/esm/components/icons/MatrixPlotIcon.1.js +51 -0
- package/dist/esm/components/icons/MatrixPlotIcon.js +53 -0
- package/dist/esm/components/icons/ScatterplotIcon.1.js +158 -0
- package/dist/esm/components/icons/ScatterplotIcon.js +138 -0
- package/dist/esm/components/icons/ViolinPlotIcon.js +36 -0
- package/dist/esm/components/matrixplot/Matrixplot.js +91 -61
- package/dist/esm/components/matrixplot/MatrixplotControls.js +10 -6
- package/dist/esm/components/obs-list/ObsItem.js +320 -228
- package/dist/esm/components/obs-list/ObsList.js +179 -142
- package/dist/esm/components/obs-list/ObsToolbar.js +3 -3
- package/dist/esm/components/obsm-list/ObsmList.js +71 -32
- package/dist/esm/components/offcanvas/index.js +68 -33
- package/dist/esm/components/pseudospatial/Pseudospatial.js +145 -88
- package/dist/esm/components/pseudospatial/PseudospatialToolbar.js +127 -78
- package/dist/esm/components/scatterplot/Scatterplot.js +243 -194
- package/dist/esm/components/scatterplot/ScatterplotControls.js +50 -35
- package/dist/esm/components/scatterplot/SpatialControls.js +155 -127
- package/dist/esm/components/scatterplot/Toolbox.js +44 -32
- package/dist/esm/components/search-bar/SearchBar.js +187 -130
- package/dist/esm/components/search-bar/SearchInfo.js +86 -91
- package/dist/esm/components/search-bar/SearchResults.js +100 -77
- package/dist/esm/components/toolbar/Toolbar.js +101 -0
- package/dist/esm/components/var-list/VarItem.js +142 -113
- package/dist/esm/components/var-list/VarList.js +108 -88
- package/dist/esm/components/var-list/VarListToolbar.js +64 -58
- package/dist/esm/components/var-list/VarSet.js +134 -115
- package/dist/esm/components/violin/Violin.js +135 -91
- package/dist/esm/components/violin/ViolinControls.js +10 -6
- package/dist/esm/constants/colorscales.js +19 -19
- package/dist/esm/constants/constants.js +53 -38
- package/dist/esm/context/DatasetContext.js +34 -23
- package/dist/esm/context/FilterContext.js +11 -8
- package/dist/esm/context/SettingsContext.js +341 -126
- package/dist/esm/context/ZarrDataContext.js +8 -6
- package/dist/esm/helpers/color-helper.js +5 -5
- package/dist/esm/helpers/map-helper.js +4 -3
- package/dist/esm/helpers/zarr-helper.js +6 -6
- package/dist/esm/index.js +22 -22
- package/dist/esm/utils/Filter.js +22 -17
- package/dist/esm/utils/Histogram.js +39 -37
- package/dist/esm/utils/ImageViewer.js +12 -8
- package/dist/esm/utils/Legend.js +44 -36
- package/dist/esm/utils/LoadingIndicators.js +16 -13
- package/dist/esm/utils/Resolver.js +201 -0
- package/dist/esm/utils/Skeleton.js +11 -10
- package/dist/esm/utils/StyledTooltip.js +38 -0
- package/dist/esm/utils/VirtualizedList.js +37 -29
- package/dist/esm/utils/errors.js +15 -15
- package/dist/esm/utils/requests.js +24 -12
- package/dist/esm/utils/search.js +7 -7
- package/dist/esm/utils/string.js +7 -7
- package/dist/esm/utils/zarrData.js +27 -28
- package/package.json +24 -10
- package/scss/cherita-bootstrap.scss +2 -2
- package/scss/cherita.scss +65 -17
- package/scss/components/accordions.scss +15 -2
- package/scss/components/layouts.scss +116 -30
- package/scss/components/lists.scss +16 -5
- package/scss/components/plotly.scss +40 -23
- package/scss/components/plots.scss +14 -1
- package/dist/cjs/components/full-page/FullPagePseudospatial.js +0 -157
- package/dist/esm/components/full-page/FullPagePseudospatial.js +0 -149
|
@@ -4,7 +4,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.Scatterplot = Scatterplot;
|
|
7
|
-
var _react =
|
|
7
|
+
var _react = require("react");
|
|
8
8
|
var _layers = require("@deck.gl/layers");
|
|
9
9
|
var _react2 = require("@deck.gl/react");
|
|
10
10
|
var _freeSolidSvgIcons = require("@fortawesome/free-solid-svg-icons");
|
|
@@ -16,6 +16,7 @@ var _reactBootstrap = require("react-bootstrap");
|
|
|
16
16
|
var _SpatialControls = require("./SpatialControls");
|
|
17
17
|
var _Toolbox = require("./Toolbox");
|
|
18
18
|
var _constants = require("../../constants/constants");
|
|
19
|
+
var _DatasetContext = require("../../context/DatasetContext");
|
|
19
20
|
var _FilterContext = require("../../context/FilterContext");
|
|
20
21
|
var _SettingsContext = require("../../context/SettingsContext");
|
|
21
22
|
var _ZarrDataContext = require("../../context/ZarrDataContext");
|
|
@@ -23,10 +24,12 @@ var _colorHelper = require("../../helpers/color-helper");
|
|
|
23
24
|
var _mapHelper = require("../../helpers/map-helper");
|
|
24
25
|
var _Legend = require("../../utils/Legend");
|
|
25
26
|
var _LoadingIndicators = require("../../utils/LoadingIndicators");
|
|
27
|
+
var _Resolver = require("../../utils/Resolver");
|
|
26
28
|
var _string = require("../../utils/string");
|
|
27
29
|
var _zarrData = require("../../utils/zarrData");
|
|
30
|
+
var _PlotAlert = require("../full-page/PlotAlert");
|
|
31
|
+
var _jsxRuntime = require("react/jsx-runtime");
|
|
28
32
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
29
|
-
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
|
|
30
33
|
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
31
34
|
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
32
35
|
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
|
|
@@ -42,13 +45,18 @@ const INITIAL_VIEW_STATE = {
|
|
|
42
45
|
bearing: 0
|
|
43
46
|
};
|
|
44
47
|
function Scatterplot(_ref) {
|
|
45
|
-
var
|
|
48
|
+
var _features$features2, _obsmData$serverError, _labelObsData$serverE, _settings$selectedVar, _data$positions;
|
|
46
49
|
let {
|
|
47
|
-
radius =
|
|
50
|
+
radius = null,
|
|
48
51
|
setShowObs,
|
|
49
52
|
setShowVars,
|
|
53
|
+
plotType,
|
|
54
|
+
setPlotType,
|
|
50
55
|
isFullscreen = false
|
|
51
56
|
} = _ref;
|
|
57
|
+
const {
|
|
58
|
+
useUnsColors
|
|
59
|
+
} = (0, _DatasetContext.useDataset)();
|
|
52
60
|
const settings = (0, _SettingsContext.useSettings)();
|
|
53
61
|
const {
|
|
54
62
|
obsIndices,
|
|
@@ -63,17 +71,21 @@ function Scatterplot(_ref) {
|
|
|
63
71
|
const deckRef = (0, _react.useRef)(null);
|
|
64
72
|
const [viewState, setViewState] = (0, _react.useState)(INITIAL_VIEW_STATE);
|
|
65
73
|
const [isRendering, setIsRendering] = (0, _react.useState)(true);
|
|
74
|
+
const [radiusScale, setRadiusScale] = (0, _react.useState)(radius || 1);
|
|
75
|
+
const [isPending, setIsPending] = (0, _react.useState)(false);
|
|
66
76
|
const [data, setData] = (0, _react.useState)({
|
|
67
|
-
ids: [],
|
|
68
77
|
positions: [],
|
|
69
|
-
values: []
|
|
70
|
-
sliceValues: []
|
|
78
|
+
values: []
|
|
71
79
|
});
|
|
80
|
+
const [coordsError, setCoordsError] = (0, _react.useState)(null);
|
|
81
|
+
const [hasObsm, setHasObsm] = (0, _react.useState)(true);
|
|
82
|
+
const [dataError, setDataError] = (0, _react.useState)(null);
|
|
83
|
+
const selectedObs = (0, _Resolver.useSelectedObs)();
|
|
72
84
|
|
|
73
85
|
// EditableGeoJsonLayer
|
|
74
86
|
const [mode, setMode] = (0, _react.useState)(() => _editModes.ViewMode);
|
|
75
87
|
const [features, setFeatures] = (0, _react.useState)({
|
|
76
|
-
type:
|
|
88
|
+
type: 'FeatureCollection',
|
|
77
89
|
features: settings.polygons[settings.selectedObsm] || []
|
|
78
90
|
});
|
|
79
91
|
const [selectedFeatureIndexes, setSelectedFeatureIndexes] = (0, _react.useState)([]);
|
|
@@ -85,24 +97,74 @@ function Scatterplot(_ref) {
|
|
|
85
97
|
const labelObsData = (0, _zarrData.useLabelObsData)();
|
|
86
98
|
// @TODO: assert length of obsmData, xData, obsData is equal
|
|
87
99
|
|
|
100
|
+
const getRadiusScale = (0, _react.useCallback)(bounds => {
|
|
101
|
+
if (!!radius) return radius;
|
|
102
|
+
// From 28 degrees ~= 30km -> 30m radius
|
|
103
|
+
const lonDim = bounds[1][0] - bounds[0][0];
|
|
104
|
+
const latDim = bounds[1][1] - bounds[0][1];
|
|
105
|
+
const minDim = Math.min(lonDim, latDim);
|
|
106
|
+
const rs = 0.01 / minDim * 111111;
|
|
107
|
+
return rs;
|
|
108
|
+
}, [radius]);
|
|
88
109
|
(0, _react.useEffect)(() => {
|
|
89
|
-
if (
|
|
90
|
-
|
|
91
|
-
|
|
110
|
+
if (obsmData.isPending || settings.colorEncoding === _constants.COLOR_ENCODINGS.VAR && xData.isPending || settings.colorEncoding === _constants.COLOR_ENCODINGS.OBS && obsData.isPending) {
|
|
111
|
+
setIsPending(true);
|
|
112
|
+
} else {
|
|
113
|
+
setIsPending(false);
|
|
92
114
|
setData(d => {
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
115
|
+
let values = d.values;
|
|
116
|
+
if (settings.colorEncoding === _constants.COLOR_ENCODINGS.VAR) {
|
|
117
|
+
if (!xData.serverError) {
|
|
118
|
+
values = xData.data;
|
|
119
|
+
setDataError(null);
|
|
120
|
+
} else {
|
|
121
|
+
values = [];
|
|
122
|
+
setDataError(xData.serverError);
|
|
123
|
+
}
|
|
124
|
+
} else if (settings.colorEncoding === _constants.COLOR_ENCODINGS.OBS) {
|
|
125
|
+
if (!obsData.serverError) {
|
|
126
|
+
values = obsData.data;
|
|
127
|
+
setDataError(null);
|
|
128
|
+
} else {
|
|
129
|
+
values = [];
|
|
130
|
+
setDataError(obsData.serverError);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
if (!obsmData.serverError && obsmData.data) {
|
|
134
|
+
if (obsmData.data[0].length !== 2) {
|
|
135
|
+
setCoordsError('Invalid coordinates. Expected 2D coordinates');
|
|
136
|
+
return {
|
|
137
|
+
positions: [],
|
|
138
|
+
values: []
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
setCoordsError(null);
|
|
142
|
+
return {
|
|
143
|
+
positions: obsmData.data,
|
|
144
|
+
values: values
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
return {
|
|
148
|
+
positions: d.positions,
|
|
149
|
+
values: values
|
|
150
|
+
};
|
|
96
151
|
});
|
|
152
|
+
}
|
|
153
|
+
}, [obsData.data, obsData.isPending, obsData.serverError, obsmData.data, obsmData.isPending, obsmData.serverError, settings.colorEncoding, xData.data, xData.isPending, xData.serverError]);
|
|
154
|
+
(0, _react.useEffect)(() => {
|
|
155
|
+
if (data.positions && !!data.positions.length) {
|
|
156
|
+
var _deckRef$current, _deckRef$current2;
|
|
97
157
|
const mapHelper = new _mapHelper.MapHelper();
|
|
98
158
|
const {
|
|
99
159
|
latitude,
|
|
100
160
|
longitude,
|
|
101
|
-
zoom
|
|
102
|
-
|
|
161
|
+
zoom,
|
|
162
|
+
bounds
|
|
163
|
+
} = mapHelper.fitBounds(data.positions, {
|
|
103
164
|
width: deckRef === null || deckRef === void 0 || (_deckRef$current = deckRef.current) === null || _deckRef$current === void 0 || (_deckRef$current = _deckRef$current.deck) === null || _deckRef$current === void 0 ? void 0 : _deckRef$current.width,
|
|
104
165
|
height: deckRef === null || deckRef === void 0 || (_deckRef$current2 = deckRef.current) === null || _deckRef$current2 === void 0 || (_deckRef$current2 = _deckRef$current2.deck) === null || _deckRef$current2 === void 0 ? void 0 : _deckRef$current2.height
|
|
105
166
|
});
|
|
167
|
+
setRadiusScale(getRadiusScale(bounds));
|
|
106
168
|
setViewState(v => {
|
|
107
169
|
return _objectSpread(_objectSpread({}, v), {}, {
|
|
108
170
|
longitude: longitude,
|
|
@@ -110,15 +172,8 @@ function Scatterplot(_ref) {
|
|
|
110
172
|
zoom: zoom
|
|
111
173
|
});
|
|
112
174
|
});
|
|
113
|
-
} else if (!obsmData.isPending && obsmData.serverError) {
|
|
114
|
-
setIsRendering(true);
|
|
115
|
-
setData(d => {
|
|
116
|
-
return _objectSpread(_objectSpread({}, d), {}, {
|
|
117
|
-
positions: []
|
|
118
|
-
});
|
|
119
|
-
});
|
|
120
175
|
}
|
|
121
|
-
}, [
|
|
176
|
+
}, [getRadiusScale, obsmData.data, obsmData.isPending, obsmData.serverError, data.positions]);
|
|
122
177
|
const getBounds = (0, _react.useCallback)(() => {
|
|
123
178
|
var _deckRef$current3, _deckRef$current4;
|
|
124
179
|
const {
|
|
@@ -135,71 +190,45 @@ function Scatterplot(_ref) {
|
|
|
135
190
|
zoom
|
|
136
191
|
};
|
|
137
192
|
}, [data.positions]);
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
setIsRendering(true);
|
|
160
|
-
if (!obsData.isPending && !obsData.serverError) {
|
|
161
|
-
setData(d => {
|
|
162
|
-
return _objectSpread(_objectSpread({}, d), {}, {
|
|
163
|
-
values: obsData.data
|
|
164
|
-
});
|
|
165
|
-
});
|
|
166
|
-
} else if (!obsData.isPending && obsData.serverError) {
|
|
167
|
-
setData(d => {
|
|
168
|
-
return _objectSpread(_objectSpread({}, d), {}, {
|
|
169
|
-
values: []
|
|
170
|
-
});
|
|
171
|
-
});
|
|
172
|
-
}
|
|
173
|
-
} else if (settings.colorEncoding === _constants.COLOR_ENCODINGS.VAR && settings.sliceBy.obs) {
|
|
174
|
-
if (!obsData.isPending && !obsData.serverError) {
|
|
175
|
-
setData(d => {
|
|
176
|
-
return _objectSpread(_objectSpread({}, d), {}, {
|
|
177
|
-
sliceValues: obsData.data
|
|
178
|
-
});
|
|
179
|
-
});
|
|
180
|
-
} else if (!obsData.isPending && obsData.serverError) {
|
|
181
|
-
setData(d => {
|
|
182
|
-
return _objectSpread(_objectSpread({}, d), {}, {
|
|
183
|
-
sliceValues: []
|
|
184
|
-
});
|
|
185
|
-
});
|
|
186
|
-
}
|
|
193
|
+
|
|
194
|
+
// Make stable references for getOriginalIndex and sortedIndexMap
|
|
195
|
+
const identityGetOriginalIndex = (0, _react.useCallback)(i => i, []);
|
|
196
|
+
const identitySortedIndexMap = (0, _react.useMemo)(() => ({
|
|
197
|
+
get: key => key
|
|
198
|
+
}), []);
|
|
199
|
+
const {
|
|
200
|
+
sortedData,
|
|
201
|
+
getOriginalIndex,
|
|
202
|
+
sortedIndexMap
|
|
203
|
+
} = (0, _react.useMemo)(() => {
|
|
204
|
+
if ((settings.colorEncoding === _constants.COLOR_ENCODINGS.VAR || settings.colorEncoding === _constants.COLOR_ENCODINGS.OBS && (selectedObs === null || selectedObs === void 0 ? void 0 : selectedObs.type) === _constants.OBS_TYPES.CONTINUOUS) && data.positions && data.values && data.positions.length === data.values.length) {
|
|
205
|
+
const sortedIndices = _lodash.default.map(data.values, (_v, i) => i).sort((a, b) => data.values[a] - data.values[b]);
|
|
206
|
+
const sortedIndexMap = new Map(_lodash.default.map(sortedIndices, (originalIndex, sortedIndex) => [originalIndex, sortedIndex]));
|
|
207
|
+
return {
|
|
208
|
+
sortedData: _lodash.default.mapValues(data, (v, _k) => {
|
|
209
|
+
return v ? _lodash.default.at(v, sortedIndices) : v;
|
|
210
|
+
}),
|
|
211
|
+
getOriginalIndex: i => sortedIndices[i],
|
|
212
|
+
sortedIndexMap: sortedIndexMap
|
|
213
|
+
};
|
|
187
214
|
}
|
|
188
|
-
|
|
215
|
+
return {
|
|
216
|
+
sortedData: data,
|
|
217
|
+
getOriginalIndex: identityGetOriginalIndex,
|
|
218
|
+
// return original index
|
|
219
|
+
sortedIndexMap: identitySortedIndexMap // return original index
|
|
220
|
+
};
|
|
221
|
+
}, [data, identityGetOriginalIndex, identitySortedIndexMap, selectedObs === null || selectedObs === void 0 ? void 0 : selectedObs.type, settings.colorEncoding]);
|
|
222
|
+
const sortedObsIndices = (0, _react.useMemo)(() => {
|
|
223
|
+
return obsIndices ? new Set(Array.from(obsIndices, i => sortedIndexMap.get(i))) : obsIndices;
|
|
224
|
+
}, [obsIndices, sortedIndexMap]);
|
|
189
225
|
const isCategorical = (0, _react.useMemo)(() => {
|
|
190
226
|
if (settings.colorEncoding === _constants.COLOR_ENCODINGS.OBS) {
|
|
191
|
-
|
|
192
|
-
return ((_settings$selectedObs = settings.selectedObs) === null || _settings$selectedObs === void 0 ? void 0 : _settings$selectedObs.type) === _constants.OBS_TYPES.CATEGORICAL || ((_settings$selectedObs2 = settings.selectedObs) === null || _settings$selectedObs2 === void 0 ? void 0 : _settings$selectedObs2.type) === _constants.OBS_TYPES.BOOLEAN;
|
|
227
|
+
return (selectedObs === null || selectedObs === void 0 ? void 0 : selectedObs.type) === _constants.OBS_TYPES.CATEGORICAL || (selectedObs === null || selectedObs === void 0 ? void 0 : selectedObs.type) === _constants.OBS_TYPES.BOOLEAN;
|
|
193
228
|
} else {
|
|
194
229
|
return false;
|
|
195
230
|
}
|
|
196
|
-
}, [settings.colorEncoding,
|
|
197
|
-
(0, _react.useEffect)(() => {
|
|
198
|
-
dispatch({
|
|
199
|
-
type: "set.controls.valueRange",
|
|
200
|
-
valueRange: [valueMin, valueMax]
|
|
201
|
-
});
|
|
202
|
-
}, [dispatch, valueMax, valueMin]);
|
|
231
|
+
}, [settings.colorEncoding, selectedObs === null || selectedObs === void 0 ? void 0 : selectedObs.type]);
|
|
203
232
|
const {
|
|
204
233
|
min,
|
|
205
234
|
max
|
|
@@ -211,28 +240,30 @@ function Scatterplot(_ref) {
|
|
|
211
240
|
let {
|
|
212
241
|
index
|
|
213
242
|
} = _ref2;
|
|
214
|
-
const grayOut =
|
|
215
|
-
return getColor({
|
|
216
|
-
value: (
|
|
243
|
+
const grayOut = isPending || sortedObsIndices && !sortedObsIndices.has(index);
|
|
244
|
+
return getColor(_objectSpread({
|
|
245
|
+
value: (sortedData.values[index] - min) / (max - min),
|
|
217
246
|
categorical: isCategorical,
|
|
218
247
|
grayOut: grayOut
|
|
219
|
-
}
|
|
220
|
-
|
|
248
|
+
}, useUnsColors && settings.colorEncoding === _constants.COLOR_ENCODINGS.OBS && selectedObs !== null && selectedObs !== void 0 && selectedObs.colors ? {
|
|
249
|
+
colorscale: selectedObs === null || selectedObs === void 0 ? void 0 : selectedObs.colors
|
|
250
|
+
} : {})) || [0, 0, 0, 100];
|
|
251
|
+
}, [isPending, sortedObsIndices, getColor, sortedData.values, min, max, isCategorical, useUnsColors, settings.colorEncoding, selectedObs === null || selectedObs === void 0 ? void 0 : selectedObs.colors]);
|
|
221
252
|
|
|
222
253
|
// @TODO: add support for pseudospatial hover to reflect in radius
|
|
223
254
|
const getRadius = (0, _react.useCallback)((_d, _ref3) => {
|
|
224
255
|
let {
|
|
225
256
|
index
|
|
226
257
|
} = _ref3;
|
|
227
|
-
const grayOut =
|
|
258
|
+
const grayOut = sortedObsIndices && !sortedObsIndices.has(index);
|
|
228
259
|
return grayOut ? 1 : 3;
|
|
229
|
-
}, [
|
|
260
|
+
}, [sortedObsIndices]);
|
|
230
261
|
const memoizedLayers = (0, _react.useMemo)(() => {
|
|
231
262
|
return [new _layers.ScatterplotLayer({
|
|
232
|
-
id:
|
|
263
|
+
id: 'cherita-layer-scatterplot',
|
|
233
264
|
pickable: true,
|
|
234
|
-
data:
|
|
235
|
-
radiusScale:
|
|
265
|
+
data: sortedData.positions,
|
|
266
|
+
radiusScale: radiusScale,
|
|
236
267
|
radiusMinPixels: 1,
|
|
237
268
|
getPosition: d => d,
|
|
238
269
|
getFillColor: getFillColor,
|
|
@@ -242,7 +273,7 @@ function Scatterplot(_ref) {
|
|
|
242
273
|
getRadius: getRadius
|
|
243
274
|
}
|
|
244
275
|
}), new _layers2.EditableGeoJsonLayer({
|
|
245
|
-
id:
|
|
276
|
+
id: 'cherita-layer-draw',
|
|
246
277
|
data: features,
|
|
247
278
|
mode: mode,
|
|
248
279
|
selectedFeatureIndexes,
|
|
@@ -254,7 +285,7 @@ function Scatterplot(_ref) {
|
|
|
254
285
|
} = _ref4;
|
|
255
286
|
setFeatures(updatedData);
|
|
256
287
|
let updatedSelectedFeatureIndexes = selectedFeatureIndexes;
|
|
257
|
-
if (editType ===
|
|
288
|
+
if (editType === 'addFeature') {
|
|
258
289
|
const {
|
|
259
290
|
featureIndexes
|
|
260
291
|
} = editContext;
|
|
@@ -275,20 +306,20 @@ function Scatterplot(_ref) {
|
|
|
275
306
|
}
|
|
276
307
|
}
|
|
277
308
|
})];
|
|
278
|
-
}, [
|
|
309
|
+
}, [sortedData.positions, features, getFillColor, getRadius, mode, radiusScale, selectedFeatureIndexes]);
|
|
279
310
|
const layers = (0, _react.useDeferredValue)(mode === _editModes.ViewMode ? memoizedLayers.reverse() : memoizedLayers); // draw scatterplot on top of polygons when in ViewMode
|
|
280
311
|
|
|
281
312
|
(0, _react.useEffect)(() => {
|
|
282
313
|
var _features$features;
|
|
283
314
|
if (!(features !== null && features !== void 0 && (_features$features = features.features) !== null && _features$features !== void 0 && _features$features.length)) {
|
|
284
315
|
dispatch({
|
|
285
|
-
type:
|
|
316
|
+
type: 'disable.slice.polygons'
|
|
286
317
|
});
|
|
287
318
|
}
|
|
288
319
|
}, [dispatch, features === null || features === void 0 || (_features$features2 = features.features) === null || _features$features2 === void 0 ? void 0 : _features$features2.length]);
|
|
289
320
|
(0, _react.useEffect)(() => {
|
|
290
321
|
dispatch({
|
|
291
|
-
type:
|
|
322
|
+
type: 'set.polygons',
|
|
292
323
|
obsm: settings.selectedObsm,
|
|
293
324
|
polygons: (features === null || features === void 0 ? void 0 : features.features) || []
|
|
294
325
|
});
|
|
@@ -298,7 +329,7 @@ function Scatterplot(_ref) {
|
|
|
298
329
|
// don't change selection while editing
|
|
299
330
|
return;
|
|
300
331
|
}
|
|
301
|
-
setSelectedFeatureIndexes(f => info.object ? info.layer.id ===
|
|
332
|
+
setSelectedFeatureIndexes(f => info.object ? info.layer.id === 'cherita-layer-draw' ? [info.index] : f : []);
|
|
302
333
|
}
|
|
303
334
|
const getLabel = function (o, v) {
|
|
304
335
|
let isVar = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
|
|
@@ -313,97 +344,114 @@ function Scatterplot(_ref) {
|
|
|
313
344
|
object,
|
|
314
345
|
index
|
|
315
346
|
} = _ref5;
|
|
316
|
-
if (!object || (object === null || object === void 0 ? void 0 : object.type) ===
|
|
347
|
+
if (!object || (object === null || object === void 0 ? void 0 : object.type) === 'Feature') return;
|
|
317
348
|
const text = [];
|
|
318
|
-
if (settings.colorEncoding === _constants.COLOR_ENCODINGS.OBS &&
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
var _obsData$data;
|
|
322
|
-
text.push(getLabel(settings.selectedObs, (_obsData$data = obsData.data) === null || _obsData$data === void 0 ? void 0 : _obsData$data[index]));
|
|
349
|
+
if (settings.colorEncoding === _constants.COLOR_ENCODINGS.OBS && selectedObs && !_lodash.default.includes(settings.labelObs, selectedObs.name)) {
|
|
350
|
+
var _data$values;
|
|
351
|
+
text.push(getLabel(selectedObs, (_data$values = data.values) === null || _data$values === void 0 ? void 0 : _data$values[getOriginalIndex(index)]));
|
|
323
352
|
}
|
|
324
353
|
if (settings.colorEncoding === _constants.COLOR_ENCODINGS.VAR && settings.selectedVar) {
|
|
325
|
-
var
|
|
326
|
-
text.push(getLabel(settings.selectedVar, (
|
|
354
|
+
var _data$values2;
|
|
355
|
+
text.push(getLabel(settings.selectedVar, (_data$values2 = data.values) === null || _data$values2 === void 0 ? void 0 : _data$values2[getOriginalIndex(index)], true));
|
|
327
356
|
}
|
|
328
357
|
if (settings.labelObs.length) {
|
|
329
358
|
text.push(..._lodash.default.map(labelObsData.data, (v, k) => {
|
|
330
|
-
const labelObs =
|
|
331
|
-
return getLabel(labelObs, v[index]);
|
|
359
|
+
const labelObs = settings.data.obs[k];
|
|
360
|
+
return getLabel(labelObs, v[getOriginalIndex(index)]);
|
|
332
361
|
}));
|
|
333
362
|
}
|
|
334
363
|
if (!text.length) return;
|
|
335
|
-
const grayOut =
|
|
364
|
+
const grayOut = sortedObsIndices && !sortedObsIndices.has(index);
|
|
336
365
|
return {
|
|
337
|
-
text: text.length ? _lodash.default.compact(text).join(
|
|
338
|
-
className: grayOut ?
|
|
366
|
+
text: text.length ? _lodash.default.compact(text).join('\n') : null,
|
|
367
|
+
className: grayOut ? 'tooltip-grayout' : 'deck-tooltip',
|
|
339
368
|
style: !grayOut ? {
|
|
340
|
-
|
|
369
|
+
'border-left': "3px solid ".concat((0, _colorHelper.rgbToHex)(getFillColor(null, {
|
|
341
370
|
index
|
|
342
371
|
})))
|
|
343
372
|
} : {
|
|
344
|
-
|
|
373
|
+
'border-left': 'none'
|
|
345
374
|
}
|
|
346
375
|
};
|
|
347
376
|
};
|
|
348
|
-
const
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
377
|
+
const error = settings.selectedObsm && ((_obsmData$serverError = obsmData.serverError) === null || _obsmData$serverError === void 0 ? void 0 : _obsmData$serverError.length) || dataError || settings.labelObs.length && ((_labelObsData$serverE = labelObsData.serverError) === null || _labelObsData$serverE === void 0 ? void 0 : _labelObsData$serverE.length) || coordsError;
|
|
378
|
+
if (!hasObsm) {
|
|
379
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_PlotAlert.PlotAlert, {
|
|
380
|
+
variant: "info",
|
|
381
|
+
heading: "Scatterplot unavailable for this dataset",
|
|
382
|
+
plotType: plotType,
|
|
383
|
+
setPlotType: setPlotType,
|
|
384
|
+
children: "This dataset does not include any embeddings, so a scatterplot cannot be displayed. Please choose a different plot type to explore the data."
|
|
385
|
+
});
|
|
386
|
+
}
|
|
387
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
|
|
388
|
+
className: "cherita-container-scatterplot",
|
|
389
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
|
|
390
|
+
className: "cherita-scatterplot",
|
|
391
|
+
children: [obsmData.isPending && /*#__PURE__*/(0, _jsxRuntime.jsx)(_LoadingIndicators.LoadingSpinner, {
|
|
392
|
+
disableShrink: true
|
|
393
|
+
}), isPending && /*#__PURE__*/(0, _jsxRuntime.jsx)(_LoadingIndicators.LoadingLinear, {}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_react2.DeckGL, {
|
|
394
|
+
viewState: viewState,
|
|
395
|
+
onViewStateChange: e => setViewState(e.viewState),
|
|
396
|
+
controller: {
|
|
397
|
+
doubleClickZoom: mode === _editModes.ViewMode
|
|
398
|
+
},
|
|
399
|
+
layers: layers,
|
|
400
|
+
onClick: onLayerClick,
|
|
401
|
+
getTooltip: getTooltip,
|
|
402
|
+
onAfterRender: () => {
|
|
403
|
+
setIsRendering(false);
|
|
404
|
+
},
|
|
405
|
+
useDevicePixels: false,
|
|
406
|
+
getCursor: _ref6 => {
|
|
407
|
+
let {
|
|
408
|
+
isDragging
|
|
409
|
+
} = _ref6;
|
|
410
|
+
return mode !== _editModes.ViewMode ? 'crosshair' : isDragging ? 'grabbing' : 'grab';
|
|
411
|
+
},
|
|
412
|
+
ref: deckRef
|
|
413
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_SpatialControls.SpatialControls, {
|
|
414
|
+
mode: mode,
|
|
415
|
+
setMode: setMode,
|
|
416
|
+
features: features,
|
|
417
|
+
setFeatures: setFeatures,
|
|
418
|
+
selectedFeatureIndexes: selectedFeatureIndexes,
|
|
419
|
+
resetBounds: () => setViewState(getBounds()),
|
|
420
|
+
increaseZoom: () => setViewState(v => _objectSpread(_objectSpread({}, v), {}, {
|
|
421
|
+
zoom: v.zoom + 1
|
|
422
|
+
})),
|
|
423
|
+
decreaseZoom: () => setViewState(v => _objectSpread(_objectSpread({}, v), {}, {
|
|
424
|
+
zoom: v.zoom - 1
|
|
425
|
+
})),
|
|
426
|
+
setShowObs: setShowObs,
|
|
427
|
+
setShowVars: setShowVars,
|
|
428
|
+
isFullscreen: isFullscreen
|
|
429
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
|
|
430
|
+
className: "cherita-spatial-footer",
|
|
431
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
|
|
432
|
+
className: "cherita-toolbox-footer",
|
|
433
|
+
children: [!!error && !isRendering && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactBootstrap.Alert, {
|
|
434
|
+
variant: "danger",
|
|
435
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactBootstrap.Alert.Heading, {
|
|
436
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactFontawesome.FontAwesomeIcon, {
|
|
437
|
+
icon: _freeSolidSvgIcons.faTriangleExclamation
|
|
438
|
+
}), "\xA0Error loading data"]
|
|
439
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)("p", {
|
|
440
|
+
className: "mb-0",
|
|
441
|
+
children: error.message
|
|
442
|
+
})]
|
|
443
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_Toolbox.Toolbox, {
|
|
444
|
+
mode: settings.colorEncoding === _constants.COLOR_ENCODINGS.VAR ? (_settings$selectedVar = settings.selectedVar) === null || _settings$selectedVar === void 0 ? void 0 : _settings$selectedVar.name : settings.colorEncoding === _constants.COLOR_ENCODINGS.OBS ? selectedObs === null || selectedObs === void 0 ? void 0 : selectedObs.name : null,
|
|
445
|
+
obsLength: parseInt((_data$positions = data.positions) === null || _data$positions === void 0 ? void 0 : _data$positions.length),
|
|
446
|
+
slicedLength: parseInt(slicedLength),
|
|
447
|
+
setHasObsm: setHasObsm
|
|
448
|
+
})]
|
|
449
|
+
}), !error && /*#__PURE__*/(0, _jsxRuntime.jsx)(_Legend.Legend, {
|
|
450
|
+
isCategorical: isCategorical,
|
|
451
|
+
min: min,
|
|
452
|
+
max: max
|
|
453
|
+
})]
|
|
454
|
+
})]
|
|
455
|
+
})
|
|
456
|
+
});
|
|
409
457
|
}
|