@haniffalab/cherita-react 1.3.0-dev.2025-06-05.2b7d4704 → 1.3.0-dev.2025-06-06.9f7ff5ad

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.
@@ -42,7 +42,7 @@ const INITIAL_VIEW_STATE = {
42
42
  bearing: 0
43
43
  };
44
44
  function Scatterplot(_ref) {
45
- var _settings$selectedObs3, _features$features2, _obsmData$serverError, _xData$serverError, _obsData$serverError, _labelObsData$serverE, _settings$selectedVar, _settings$selectedObs4, _obsmData$data;
45
+ var _settings$selectedObs2, _settings$selectedObs5, _features$features2, _obsmData$serverError, _xData$serverError, _obsData$serverError, _labelObsData$serverE, _settings$selectedVar, _settings$selectedObs6, _data$positions;
46
46
  let {
47
47
  radius = null,
48
48
  setShowObs,
@@ -63,13 +63,12 @@ function Scatterplot(_ref) {
63
63
  const deckRef = (0, _react.useRef)(null);
64
64
  const [viewState, setViewState] = (0, _react.useState)(INITIAL_VIEW_STATE);
65
65
  const [isRendering, setIsRendering] = (0, _react.useState)(true);
66
+ const [radiusScale, setRadiusScale] = (0, _react.useState)(radius || 1);
67
+ const [isPending, setIsPending] = (0, _react.useState)(false);
66
68
  const [data, setData] = (0, _react.useState)({
67
- ids: [],
68
69
  positions: [],
69
- values: [],
70
- sliceValues: []
70
+ values: []
71
71
  });
72
- const [radiusScale, setRadiusScale] = (0, _react.useState)(radius || 1);
73
72
 
74
73
  // EditableGeoJsonLayer
75
74
  const [mode, setMode] = (0, _react.useState)(() => _editModes.ViewMode);
@@ -96,21 +95,34 @@ function Scatterplot(_ref) {
96
95
  return rs;
97
96
  }, [radius]);
98
97
  (0, _react.useEffect)(() => {
99
- if (!obsmData.isPending && !obsmData.serverError) {
100
- var _deckRef$current, _deckRef$current2;
101
- setIsRendering(true);
98
+ if (obsmData.isPending || settings.colorEncoding === _constants.COLOR_ENCODINGS.VAR && xData.isPending || settings.colorEncoding === _constants.COLOR_ENCODINGS.OBS && obsData.isPending) {
99
+ setIsPending(true);
100
+ } else {
101
+ setIsPending(false);
102
102
  setData(d => {
103
- return _objectSpread(_objectSpread({}, d), {}, {
104
- positions: obsmData.data
105
- });
103
+ let values = d.values;
104
+ if (settings.colorEncoding === _constants.COLOR_ENCODINGS.VAR) {
105
+ values = !xData.serverError ? xData.data : values;
106
+ } else if (settings.colorEncoding === _constants.COLOR_ENCODINGS.OBS) {
107
+ values = !obsData.serverError ? obsData.data : values;
108
+ }
109
+ return {
110
+ positions: !obsmData.serverError ? obsmData.data : d.positions,
111
+ values: values
112
+ };
106
113
  });
114
+ }
115
+ }, [obsData.data, obsData.isPending, obsData.serverError, obsmData.data, obsmData.isPending, obsmData.serverError, settings.colorEncoding, xData.data, xData.isPending, xData.serverError]);
116
+ (0, _react.useEffect)(() => {
117
+ if (data.positions && !!data.positions.length) {
118
+ var _deckRef$current, _deckRef$current2;
107
119
  const mapHelper = new _mapHelper.MapHelper();
108
120
  const {
109
121
  latitude,
110
122
  longitude,
111
123
  zoom,
112
124
  bounds
113
- } = mapHelper.fitBounds(obsmData.data, {
125
+ } = mapHelper.fitBounds(data.positions, {
114
126
  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,
115
127
  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
116
128
  });
@@ -122,15 +134,8 @@ function Scatterplot(_ref) {
122
134
  zoom: zoom
123
135
  });
124
136
  });
125
- } else if (!obsmData.isPending && obsmData.serverError) {
126
- setIsRendering(true);
127
- setData(d => {
128
- return _objectSpread(_objectSpread({}, d), {}, {
129
- positions: []
130
- });
131
- });
132
137
  }
133
- }, [settings.selectedObsm, getRadiusScale, obsmData.data, obsmData.isPending, obsmData.serverError]);
138
+ }, [settings.selectedObsm, getRadiusScale, obsmData.data, obsmData.isPending, obsmData.serverError, data.positions]);
134
139
  const getBounds = (0, _react.useCallback)(() => {
135
140
  var _deckRef$current3, _deckRef$current4;
136
141
  const {
@@ -147,65 +152,47 @@ function Scatterplot(_ref) {
147
152
  zoom
148
153
  };
149
154
  }, [data.positions]);
150
- (0, _react.useEffect)(() => {
151
- if (settings.colorEncoding === _constants.COLOR_ENCODINGS.VAR) {
152
- setIsRendering(true);
153
- if (!xData.isPending && !xData.serverError) {
154
- // @TODO: add condition to check obs slicing
155
- setData(d => {
156
- return _objectSpread(_objectSpread({}, d), {}, {
157
- values: xData.data
158
- });
159
- });
160
- } else if (!xData.isPending && xData.serverError) {
161
- setData(d => {
162
- return _objectSpread(_objectSpread({}, d), {}, {
163
- values: []
164
- });
165
- });
166
- }
167
- }
168
- }, [settings.colorEncoding, xData.data, xData.isPending, xData.serverError, getColor]);
169
- (0, _react.useEffect)(() => {
170
- if (settings.colorEncoding === _constants.COLOR_ENCODINGS.OBS) {
171
- setIsRendering(true);
172
- if (!obsData.isPending && !obsData.serverError) {
173
- setData(d => {
174
- return _objectSpread(_objectSpread({}, d), {}, {
175
- values: obsData.data
176
- });
177
- });
178
- } else if (!obsData.isPending && obsData.serverError) {
179
- setData(d => {
180
- return _objectSpread(_objectSpread({}, d), {}, {
181
- values: []
182
- });
183
- });
184
- }
185
- } else if (settings.colorEncoding === _constants.COLOR_ENCODINGS.VAR && settings.sliceBy.obs) {
186
- if (!obsData.isPending && !obsData.serverError) {
187
- setData(d => {
188
- return _objectSpread(_objectSpread({}, d), {}, {
189
- sliceValues: obsData.data
190
- });
191
- });
192
- } else if (!obsData.isPending && obsData.serverError) {
193
- setData(d => {
194
- return _objectSpread(_objectSpread({}, d), {}, {
195
- sliceValues: []
196
- });
197
- });
198
- }
155
+
156
+ // Make stable references for getOriginalIndex and sortedIndexMap
157
+ const identityGetOriginalIndex = (0, _react.useCallback)(i => i, []);
158
+ const identitySortedIndexMap = (0, _react.useMemo)(() => ({
159
+ get: key => key
160
+ }), []);
161
+ const {
162
+ sortedData,
163
+ getOriginalIndex,
164
+ sortedIndexMap
165
+ } = (0, _react.useMemo)(() => {
166
+ var _settings$selectedObs;
167
+ if ((settings.colorEncoding === _constants.COLOR_ENCODINGS.VAR || settings.colorEncoding === _constants.COLOR_ENCODINGS.OBS && ((_settings$selectedObs = settings.selectedObs) === null || _settings$selectedObs === void 0 ? void 0 : _settings$selectedObs.type) === _constants.OBS_TYPES.CONTINUOUS) && data.positions && data.values && data.positions.length === data.values.length) {
168
+ const sortedIndices = _lodash.default.map(data.values, (_v, i) => i).sort((a, b) => data.values[a] - data.values[b]);
169
+ const sortedIndexMap = new Map(_lodash.default.map(sortedIndices, (originalIndex, sortedIndex) => [originalIndex, sortedIndex]));
170
+ return {
171
+ sortedData: _lodash.default.mapValues(data, (v, _k) => {
172
+ return v ? _lodash.default.at(v, sortedIndices) : v;
173
+ }),
174
+ getOriginalIndex: i => sortedIndices[i],
175
+ sortedIndexMap: sortedIndexMap
176
+ };
199
177
  }
200
- }, [settings.colorEncoding, obsData.data, obsData.isPending, obsData.serverError, settings.sliceBy.obs]);
178
+ return {
179
+ sortedData: data,
180
+ getOriginalIndex: identityGetOriginalIndex,
181
+ // return original index
182
+ sortedIndexMap: identitySortedIndexMap // return original index
183
+ };
184
+ }, [data, identityGetOriginalIndex, identitySortedIndexMap, settings.colorEncoding, (_settings$selectedObs2 = settings.selectedObs) === null || _settings$selectedObs2 === void 0 ? void 0 : _settings$selectedObs2.type]);
185
+ const sortedObsIndices = (0, _react.useMemo)(() => {
186
+ return obsIndices ? new Set(Array.from(obsIndices, i => sortedIndexMap.get(i))) : obsIndices;
187
+ }, [obsIndices, sortedIndexMap]);
201
188
  const isCategorical = (0, _react.useMemo)(() => {
202
189
  if (settings.colorEncoding === _constants.COLOR_ENCODINGS.OBS) {
203
- var _settings$selectedObs, _settings$selectedObs2;
204
- 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;
190
+ var _settings$selectedObs3, _settings$selectedObs4;
191
+ return ((_settings$selectedObs3 = settings.selectedObs) === null || _settings$selectedObs3 === void 0 ? void 0 : _settings$selectedObs3.type) === _constants.OBS_TYPES.CATEGORICAL || ((_settings$selectedObs4 = settings.selectedObs) === null || _settings$selectedObs4 === void 0 ? void 0 : _settings$selectedObs4.type) === _constants.OBS_TYPES.BOOLEAN;
205
192
  } else {
206
193
  return false;
207
194
  }
208
- }, [settings.colorEncoding, (_settings$selectedObs3 = settings.selectedObs) === null || _settings$selectedObs3 === void 0 ? void 0 : _settings$selectedObs3.type]);
195
+ }, [settings.colorEncoding, (_settings$selectedObs5 = settings.selectedObs) === null || _settings$selectedObs5 === void 0 ? void 0 : _settings$selectedObs5.type]);
209
196
  (0, _react.useEffect)(() => {
210
197
  dispatch({
211
198
  type: "set.controls.valueRange",
@@ -223,27 +210,27 @@ function Scatterplot(_ref) {
223
210
  let {
224
211
  index
225
212
  } = _ref2;
226
- const grayOut = obsIndices && !obsIndices.has(index);
213
+ const grayOut = isPending || sortedObsIndices && !sortedObsIndices.has(index);
227
214
  return getColor({
228
- value: (data.values[index] - min) / (max - min),
215
+ value: (sortedData.values[index] - min) / (max - min),
229
216
  categorical: isCategorical,
230
217
  grayOut: grayOut
231
218
  }) || [0, 0, 0, 100];
232
- }, [data.values, obsIndices, getColor, isCategorical, max, min]);
219
+ }, [isPending, sortedObsIndices, getColor, sortedData.values, min, max, isCategorical]);
233
220
 
234
221
  // @TODO: add support for pseudospatial hover to reflect in radius
235
222
  const getRadius = (0, _react.useCallback)((_d, _ref3) => {
236
223
  let {
237
224
  index
238
225
  } = _ref3;
239
- const grayOut = obsIndices && !obsIndices.has(index);
226
+ const grayOut = sortedObsIndices && !sortedObsIndices.has(index);
240
227
  return grayOut ? 1 : 3;
241
- }, [obsIndices]);
228
+ }, [sortedObsIndices]);
242
229
  const memoizedLayers = (0, _react.useMemo)(() => {
243
230
  return [new _layers.ScatterplotLayer({
244
231
  id: "cherita-layer-scatterplot",
245
232
  pickable: true,
246
- data: data.positions,
233
+ data: sortedData.positions,
247
234
  radiusScale: radiusScale,
248
235
  radiusMinPixels: 1,
249
236
  getPosition: d => d,
@@ -287,7 +274,7 @@ function Scatterplot(_ref) {
287
274
  }
288
275
  }
289
276
  })];
290
- }, [data.positions, features, getFillColor, getRadius, mode, radiusScale, selectedFeatureIndexes]);
277
+ }, [sortedData.positions, features, getFillColor, getRadius, mode, radiusScale, selectedFeatureIndexes]);
291
278
  const layers = (0, _react.useDeferredValue)(mode === _editModes.ViewMode ? memoizedLayers.reverse() : memoizedLayers); // draw scatterplot on top of polygons when in ViewMode
292
279
 
293
280
  (0, _react.useEffect)(() => {
@@ -330,21 +317,21 @@ function Scatterplot(_ref) {
330
317
  if (settings.colorEncoding === _constants.COLOR_ENCODINGS.OBS && settings.selectedObs && !_lodash.default.some(settings.labelObs, {
331
318
  name: settings.selectedObs.name
332
319
  })) {
333
- var _obsData$data;
334
- text.push(getLabel(settings.selectedObs, (_obsData$data = obsData.data) === null || _obsData$data === void 0 ? void 0 : _obsData$data[index]));
320
+ var _data$values;
321
+ text.push(getLabel(settings.selectedObs, (_data$values = data.values) === null || _data$values === void 0 ? void 0 : _data$values[getOriginalIndex(index)]));
335
322
  }
336
323
  if (settings.colorEncoding === _constants.COLOR_ENCODINGS.VAR && settings.selectedVar) {
337
- var _xData$data;
338
- text.push(getLabel(settings.selectedVar, (_xData$data = xData.data) === null || _xData$data === void 0 ? void 0 : _xData$data[index], true));
324
+ var _data$values2;
325
+ text.push(getLabel(settings.selectedVar, (_data$values2 = data.values) === null || _data$values2 === void 0 ? void 0 : _data$values2[getOriginalIndex(index)], true));
339
326
  }
340
327
  if (settings.labelObs.length) {
341
328
  text.push(..._lodash.default.map(labelObsData.data, (v, k) => {
342
329
  const labelObs = _lodash.default.find(settings.labelObs, o => o.name === k);
343
- return getLabel(labelObs, v[index]);
330
+ return getLabel(labelObs, v[getOriginalIndex(index)]);
344
331
  }));
345
332
  }
346
333
  if (!text.length) return;
347
- const grayOut = obsIndices && !obsIndices.has(index);
334
+ const grayOut = sortedObsIndices && !sortedObsIndices.has(index);
348
335
  return {
349
336
  text: text.length ? _lodash.default.compact(text).join("\n") : null,
350
337
  className: grayOut ? "tooltip-grayout" : "deck-tooltip",
@@ -357,8 +344,7 @@ function Scatterplot(_ref) {
357
344
  }
358
345
  };
359
346
  };
360
- const isPending = (isRendering || xData.isPending || obsmData.isPending) && !obsmData.isPending;
361
- const error = settings.selectedObsm && ((_obsmData$serverError = obsmData.serverError) === null || _obsmData$serverError === void 0 ? void 0 : _obsmData$serverError.length) || settings.colorEncoding === _constants.COLOR_ENCODINGS.VAR && ((_xData$serverError = xData.serverError) === null || _xData$serverError === void 0 ? void 0 : _xData$serverError.length) || settings.colorEncoding === _constants.COLOR_ENCODINGS.OBS && ((_obsData$serverError = obsData.serverError) === null || _obsData$serverError === void 0 ? void 0 : _obsData$serverError.length) || settings.labelObs.lengh && ((_labelObsData$serverE = labelObsData.serverError) === null || _labelObsData$serverE === void 0 ? void 0 : _labelObsData$serverE.length);
347
+ const error = settings.selectedObsm && ((_obsmData$serverError = obsmData.serverError) === null || _obsmData$serverError === void 0 ? void 0 : _obsmData$serverError.length) || settings.colorEncoding === _constants.COLOR_ENCODINGS.VAR && ((_xData$serverError = xData.serverError) === null || _xData$serverError === void 0 ? void 0 : _xData$serverError.length) || settings.colorEncoding === _constants.COLOR_ENCODINGS.OBS && ((_obsData$serverError = obsData.serverError) === null || _obsData$serverError === void 0 ? void 0 : _obsData$serverError.length) || settings.labelObs.length && ((_labelObsData$serverE = labelObsData.serverError) === null || _labelObsData$serverE === void 0 ? void 0 : _labelObsData$serverE.length);
362
348
  return /*#__PURE__*/_react.default.createElement("div", {
363
349
  className: "cherita-container-scatterplot"
364
350
  }, /*#__PURE__*/_react.default.createElement("div", {
@@ -405,13 +391,13 @@ function Scatterplot(_ref) {
405
391
  className: "cherita-spatial-footer"
406
392
  }, /*#__PURE__*/_react.default.createElement("div", {
407
393
  className: "cherita-toolbox-footer"
408
- }, error && !isPending && /*#__PURE__*/_react.default.createElement(_reactBootstrap.Alert, {
394
+ }, !!error && !isRendering && /*#__PURE__*/_react.default.createElement(_reactBootstrap.Alert, {
409
395
  variant: "danger"
410
396
  }, /*#__PURE__*/_react.default.createElement(_reactFontawesome.FontAwesomeIcon, {
411
397
  icon: _freeSolidSvgIcons.faTriangleExclamation
412
398
  }), "\xA0Error loading data"), /*#__PURE__*/_react.default.createElement(_Toolbox.Toolbox, {
413
- 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 ? (_settings$selectedObs4 = settings.selectedObs) === null || _settings$selectedObs4 === void 0 ? void 0 : _settings$selectedObs4.name : null,
414
- obsLength: parseInt((_obsmData$data = obsmData.data) === null || _obsmData$data === void 0 ? void 0 : _obsmData$data.length),
399
+ 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 ? (_settings$selectedObs6 = settings.selectedObs) === null || _settings$selectedObs6 === void 0 ? void 0 : _settings$selectedObs6.name : null,
400
+ obsLength: parseInt((_data$positions = data.positions) === null || _data$positions === void 0 ? void 0 : _data$positions.length),
415
401
  slicedLength: parseInt(slicedLength)
416
402
  })), /*#__PURE__*/_react.default.createElement(_Legend.Legend, {
417
403
  isCategorical: isCategorical,
@@ -15,6 +15,7 @@ var _DatasetContext = require("../../context/DatasetContext");
15
15
  var _SettingsContext = require("../../context/SettingsContext");
16
16
  var _requests = require("../../utils/requests");
17
17
  var _VarItem = require("../var-list/VarItem");
18
+ var _VarList = require("../var-list/VarList");
18
19
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
19
20
  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); }
20
21
  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; }
@@ -52,39 +53,6 @@ function VarInfo(_ref) {
52
53
  data: fetchedData
53
54
  })));
54
55
  }
55
- const useVarMean = function (varKeys) {
56
- let enabled = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
57
- const ENDPOINT = "matrix/mean";
58
- const dataset = (0, _DatasetContext.useDataset)();
59
- const [params, setParams] = (0, _react.useState)({
60
- url: dataset.url,
61
- varKeys: _lodash.default.map(varKeys, v => v.isSet ? {
62
- name: v.name,
63
- indices: v.vars.map(v => v.index)
64
- } : v.index),
65
- // obsIndices:
66
- varNamesCol: dataset.varNamesCol
67
- });
68
- (0, _react.useEffect)(() => {
69
- setParams(p => {
70
- return _objectSpread(_objectSpread({}, p), {}, {
71
- varKeys: _lodash.default.map(varKeys, v => v.isSet ? {
72
- name: v.name,
73
- indices: v.vars.map(v => v.index)
74
- } : v.index)
75
- });
76
- });
77
- }, [varKeys]);
78
- return (0, _requests.useFetch)(ENDPOINT, params, {
79
- enabled: enabled,
80
- refetchOnMount: false
81
- });
82
- };
83
-
84
- // ensure nulls are lowest values
85
- const sortMeans = (i, means) => {
86
- return means[i.name] || _lodash.default.min(_lodash.default.values(means)) - 1;
87
- };
88
56
  function DiseaseInfo(_ref2) {
89
57
  let {
90
58
  disease,
@@ -119,12 +87,12 @@ function DiseaseInfo(_ref2) {
119
87
  setDiseaseVars(diseaseData.fetchedData);
120
88
  }
121
89
  }, [diseaseData.fetchedData, diseaseData.isPending, diseaseData.serverError]);
122
- const varMeans = useVarMean(diseaseVars, !!(diseaseVars !== null && diseaseVars !== void 0 && diseaseVars.length) && settings.varSort.disease.sort === _constants.VAR_SORT.MATRIX);
90
+ const varMeans = (0, _VarList.useVarMean)(diseaseVars, !!(diseaseVars !== null && diseaseVars !== void 0 && diseaseVars.length) && settings.varSort.disease.sort === _constants.VAR_SORT.MATRIX);
123
91
  (0, _react.useEffect)(() => {
124
92
  if (settings.varSort.disease.sort === _constants.VAR_SORT.MATRIX) {
125
93
  if (!varMeans.isPending && !varMeans.serverError) {
126
94
  setSortedDiseaseVars(_lodash.default.orderBy(diseaseVars, o => {
127
- return sortMeans(o, varMeans.fetchedData);
95
+ return (0, _VarList.sortMeans)(o, varMeans.fetchedData);
128
96
  }, settings.varSort.disease.sortOrder));
129
97
  }
130
98
  } else if (settings.varSort.disease.sort === _constants.VAR_SORT.NAME) {
@@ -4,6 +4,7 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.VarNamesList = VarNamesList;
7
+ exports.useVarMean = exports.sortMeans = void 0;
7
8
  var _react = _interopRequireWildcard(require("react"));
8
9
  var _freeSolidSvgIcons = require("@fortawesome/free-solid-svg-icons");
9
10
  var _reactFontawesome = require("@fortawesome/react-fontawesome");
@@ -15,6 +16,7 @@ var _VarListToolbar = require("./VarListToolbar");
15
16
  var _VarSet = require("./VarSet");
16
17
  var _constants = require("../../constants/constants");
17
18
  var _DatasetContext = require("../../context/DatasetContext");
19
+ var _FilterContext = require("../../context/FilterContext");
18
20
  var _SettingsContext = require("../../context/SettingsContext");
19
21
  var _LoadingIndicators = require("../../utils/LoadingIndicators");
20
22
  var _requests = require("../../utils/requests");
@@ -29,13 +31,16 @@ const useVarMean = function (varKeys) {
29
31
  let enabled = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
30
32
  const ENDPOINT = "matrix/mean";
31
33
  const dataset = (0, _DatasetContext.useDataset)();
34
+ const {
35
+ obsIndices
36
+ } = (0, _FilterContext.useFilteredData)();
32
37
  const [params, setParams] = (0, _react.useState)({
33
38
  url: dataset.url,
34
39
  varKeys: _lodash.default.map(varKeys, v => v.isSet ? {
35
40
  name: v.name,
36
41
  indices: v.vars.map(v => v.index)
37
42
  } : v.index),
38
- // obsIndices:
43
+ obsIndices: obsIndices,
39
44
  varNamesCol: dataset.varNamesCol
40
45
  });
41
46
  (0, _react.useEffect)(() => {
@@ -44,10 +49,11 @@ const useVarMean = function (varKeys) {
44
49
  varKeys: _lodash.default.map(varKeys, v => v.isSet ? {
45
50
  name: v.name,
46
51
  indices: v.vars.map(v => v.index)
47
- } : v.index)
52
+ } : v.index),
53
+ obsIndices: obsIndices
48
54
  });
49
55
  });
50
- }, [varKeys]);
56
+ }, [obsIndices, varKeys]);
51
57
  return (0, _requests.useFetch)(ENDPOINT, params, {
52
58
  enabled: enabled,
53
59
  refetchOnMount: false
@@ -55,9 +61,11 @@ const useVarMean = function (varKeys) {
55
61
  };
56
62
 
57
63
  // ensure nulls are lowest values
64
+ exports.useVarMean = useVarMean;
58
65
  const sortMeans = (i, means) => {
59
66
  return means[i.name] || _lodash.default.min(_lodash.default.values(means)) - 1;
60
67
  };
68
+ exports.sortMeans = sortMeans;
61
69
  function VarNamesList(_ref) {
62
70
  var _settings$selectedVar, _settings$selectedVar2;
63
71
  let {
@@ -34,7 +34,7 @@ const INITIAL_VIEW_STATE = {
34
34
  bearing: 0
35
35
  };
36
36
  export function Scatterplot(_ref) {
37
- var _settings$selectedObs3, _features$features2, _obsmData$serverError, _xData$serverError, _obsData$serverError, _labelObsData$serverE, _settings$selectedVar, _settings$selectedObs4, _obsmData$data;
37
+ var _settings$selectedObs2, _settings$selectedObs5, _features$features2, _obsmData$serverError, _xData$serverError, _obsData$serverError, _labelObsData$serverE, _settings$selectedVar, _settings$selectedObs6, _data$positions;
38
38
  let {
39
39
  radius = null,
40
40
  setShowObs,
@@ -55,13 +55,12 @@ export function Scatterplot(_ref) {
55
55
  const deckRef = useRef(null);
56
56
  const [viewState, setViewState] = useState(INITIAL_VIEW_STATE);
57
57
  const [isRendering, setIsRendering] = useState(true);
58
+ const [radiusScale, setRadiusScale] = useState(radius || 1);
59
+ const [isPending, setIsPending] = useState(false);
58
60
  const [data, setData] = useState({
59
- ids: [],
60
61
  positions: [],
61
- values: [],
62
- sliceValues: []
62
+ values: []
63
63
  });
64
- const [radiusScale, setRadiusScale] = useState(radius || 1);
65
64
 
66
65
  // EditableGeoJsonLayer
67
66
  const [mode, setMode] = useState(() => ViewMode);
@@ -88,21 +87,34 @@ export function Scatterplot(_ref) {
88
87
  return rs;
89
88
  }, [radius]);
90
89
  useEffect(() => {
91
- if (!obsmData.isPending && !obsmData.serverError) {
92
- var _deckRef$current, _deckRef$current2;
93
- setIsRendering(true);
90
+ if (obsmData.isPending || settings.colorEncoding === COLOR_ENCODINGS.VAR && xData.isPending || settings.colorEncoding === COLOR_ENCODINGS.OBS && obsData.isPending) {
91
+ setIsPending(true);
92
+ } else {
93
+ setIsPending(false);
94
94
  setData(d => {
95
- return _objectSpread(_objectSpread({}, d), {}, {
96
- positions: obsmData.data
97
- });
95
+ let values = d.values;
96
+ if (settings.colorEncoding === COLOR_ENCODINGS.VAR) {
97
+ values = !xData.serverError ? xData.data : values;
98
+ } else if (settings.colorEncoding === COLOR_ENCODINGS.OBS) {
99
+ values = !obsData.serverError ? obsData.data : values;
100
+ }
101
+ return {
102
+ positions: !obsmData.serverError ? obsmData.data : d.positions,
103
+ values: values
104
+ };
98
105
  });
106
+ }
107
+ }, [obsData.data, obsData.isPending, obsData.serverError, obsmData.data, obsmData.isPending, obsmData.serverError, settings.colorEncoding, xData.data, xData.isPending, xData.serverError]);
108
+ useEffect(() => {
109
+ if (data.positions && !!data.positions.length) {
110
+ var _deckRef$current, _deckRef$current2;
99
111
  const mapHelper = new MapHelper();
100
112
  const {
101
113
  latitude,
102
114
  longitude,
103
115
  zoom,
104
116
  bounds
105
- } = mapHelper.fitBounds(obsmData.data, {
117
+ } = mapHelper.fitBounds(data.positions, {
106
118
  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,
107
119
  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
108
120
  });
@@ -114,15 +126,8 @@ export function Scatterplot(_ref) {
114
126
  zoom: zoom
115
127
  });
116
128
  });
117
- } else if (!obsmData.isPending && obsmData.serverError) {
118
- setIsRendering(true);
119
- setData(d => {
120
- return _objectSpread(_objectSpread({}, d), {}, {
121
- positions: []
122
- });
123
- });
124
129
  }
125
- }, [settings.selectedObsm, getRadiusScale, obsmData.data, obsmData.isPending, obsmData.serverError]);
130
+ }, [settings.selectedObsm, getRadiusScale, obsmData.data, obsmData.isPending, obsmData.serverError, data.positions]);
126
131
  const getBounds = useCallback(() => {
127
132
  var _deckRef$current3, _deckRef$current4;
128
133
  const {
@@ -139,65 +144,47 @@ export function Scatterplot(_ref) {
139
144
  zoom
140
145
  };
141
146
  }, [data.positions]);
142
- useEffect(() => {
143
- if (settings.colorEncoding === COLOR_ENCODINGS.VAR) {
144
- setIsRendering(true);
145
- if (!xData.isPending && !xData.serverError) {
146
- // @TODO: add condition to check obs slicing
147
- setData(d => {
148
- return _objectSpread(_objectSpread({}, d), {}, {
149
- values: xData.data
150
- });
151
- });
152
- } else if (!xData.isPending && xData.serverError) {
153
- setData(d => {
154
- return _objectSpread(_objectSpread({}, d), {}, {
155
- values: []
156
- });
157
- });
158
- }
159
- }
160
- }, [settings.colorEncoding, xData.data, xData.isPending, xData.serverError, getColor]);
161
- useEffect(() => {
162
- if (settings.colorEncoding === COLOR_ENCODINGS.OBS) {
163
- setIsRendering(true);
164
- if (!obsData.isPending && !obsData.serverError) {
165
- setData(d => {
166
- return _objectSpread(_objectSpread({}, d), {}, {
167
- values: obsData.data
168
- });
169
- });
170
- } else if (!obsData.isPending && obsData.serverError) {
171
- setData(d => {
172
- return _objectSpread(_objectSpread({}, d), {}, {
173
- values: []
174
- });
175
- });
176
- }
177
- } else if (settings.colorEncoding === COLOR_ENCODINGS.VAR && settings.sliceBy.obs) {
178
- if (!obsData.isPending && !obsData.serverError) {
179
- setData(d => {
180
- return _objectSpread(_objectSpread({}, d), {}, {
181
- sliceValues: obsData.data
182
- });
183
- });
184
- } else if (!obsData.isPending && obsData.serverError) {
185
- setData(d => {
186
- return _objectSpread(_objectSpread({}, d), {}, {
187
- sliceValues: []
188
- });
189
- });
190
- }
147
+
148
+ // Make stable references for getOriginalIndex and sortedIndexMap
149
+ const identityGetOriginalIndex = useCallback(i => i, []);
150
+ const identitySortedIndexMap = useMemo(() => ({
151
+ get: key => key
152
+ }), []);
153
+ const {
154
+ sortedData,
155
+ getOriginalIndex,
156
+ sortedIndexMap
157
+ } = useMemo(() => {
158
+ var _settings$selectedObs;
159
+ if ((settings.colorEncoding === COLOR_ENCODINGS.VAR || settings.colorEncoding === COLOR_ENCODINGS.OBS && ((_settings$selectedObs = settings.selectedObs) === null || _settings$selectedObs === void 0 ? void 0 : _settings$selectedObs.type) === OBS_TYPES.CONTINUOUS) && data.positions && data.values && data.positions.length === data.values.length) {
160
+ const sortedIndices = _.map(data.values, (_v, i) => i).sort((a, b) => data.values[a] - data.values[b]);
161
+ const sortedIndexMap = new Map(_.map(sortedIndices, (originalIndex, sortedIndex) => [originalIndex, sortedIndex]));
162
+ return {
163
+ sortedData: _.mapValues(data, (v, _k) => {
164
+ return v ? _.at(v, sortedIndices) : v;
165
+ }),
166
+ getOriginalIndex: i => sortedIndices[i],
167
+ sortedIndexMap: sortedIndexMap
168
+ };
191
169
  }
192
- }, [settings.colorEncoding, obsData.data, obsData.isPending, obsData.serverError, settings.sliceBy.obs]);
170
+ return {
171
+ sortedData: data,
172
+ getOriginalIndex: identityGetOriginalIndex,
173
+ // return original index
174
+ sortedIndexMap: identitySortedIndexMap // return original index
175
+ };
176
+ }, [data, identityGetOriginalIndex, identitySortedIndexMap, settings.colorEncoding, (_settings$selectedObs2 = settings.selectedObs) === null || _settings$selectedObs2 === void 0 ? void 0 : _settings$selectedObs2.type]);
177
+ const sortedObsIndices = useMemo(() => {
178
+ return obsIndices ? new Set(Array.from(obsIndices, i => sortedIndexMap.get(i))) : obsIndices;
179
+ }, [obsIndices, sortedIndexMap]);
193
180
  const isCategorical = useMemo(() => {
194
181
  if (settings.colorEncoding === COLOR_ENCODINGS.OBS) {
195
- var _settings$selectedObs, _settings$selectedObs2;
196
- return ((_settings$selectedObs = settings.selectedObs) === null || _settings$selectedObs === void 0 ? void 0 : _settings$selectedObs.type) === OBS_TYPES.CATEGORICAL || ((_settings$selectedObs2 = settings.selectedObs) === null || _settings$selectedObs2 === void 0 ? void 0 : _settings$selectedObs2.type) === OBS_TYPES.BOOLEAN;
182
+ var _settings$selectedObs3, _settings$selectedObs4;
183
+ return ((_settings$selectedObs3 = settings.selectedObs) === null || _settings$selectedObs3 === void 0 ? void 0 : _settings$selectedObs3.type) === OBS_TYPES.CATEGORICAL || ((_settings$selectedObs4 = settings.selectedObs) === null || _settings$selectedObs4 === void 0 ? void 0 : _settings$selectedObs4.type) === OBS_TYPES.BOOLEAN;
197
184
  } else {
198
185
  return false;
199
186
  }
200
- }, [settings.colorEncoding, (_settings$selectedObs3 = settings.selectedObs) === null || _settings$selectedObs3 === void 0 ? void 0 : _settings$selectedObs3.type]);
187
+ }, [settings.colorEncoding, (_settings$selectedObs5 = settings.selectedObs) === null || _settings$selectedObs5 === void 0 ? void 0 : _settings$selectedObs5.type]);
201
188
  useEffect(() => {
202
189
  dispatch({
203
190
  type: "set.controls.valueRange",
@@ -215,27 +202,27 @@ export function Scatterplot(_ref) {
215
202
  let {
216
203
  index
217
204
  } = _ref2;
218
- const grayOut = obsIndices && !obsIndices.has(index);
205
+ const grayOut = isPending || sortedObsIndices && !sortedObsIndices.has(index);
219
206
  return getColor({
220
- value: (data.values[index] - min) / (max - min),
207
+ value: (sortedData.values[index] - min) / (max - min),
221
208
  categorical: isCategorical,
222
209
  grayOut: grayOut
223
210
  }) || [0, 0, 0, 100];
224
- }, [data.values, obsIndices, getColor, isCategorical, max, min]);
211
+ }, [isPending, sortedObsIndices, getColor, sortedData.values, min, max, isCategorical]);
225
212
 
226
213
  // @TODO: add support for pseudospatial hover to reflect in radius
227
214
  const getRadius = useCallback((_d, _ref3) => {
228
215
  let {
229
216
  index
230
217
  } = _ref3;
231
- const grayOut = obsIndices && !obsIndices.has(index);
218
+ const grayOut = sortedObsIndices && !sortedObsIndices.has(index);
232
219
  return grayOut ? 1 : 3;
233
- }, [obsIndices]);
220
+ }, [sortedObsIndices]);
234
221
  const memoizedLayers = useMemo(() => {
235
222
  return [new ScatterplotLayer({
236
223
  id: "cherita-layer-scatterplot",
237
224
  pickable: true,
238
- data: data.positions,
225
+ data: sortedData.positions,
239
226
  radiusScale: radiusScale,
240
227
  radiusMinPixels: 1,
241
228
  getPosition: d => d,
@@ -279,7 +266,7 @@ export function Scatterplot(_ref) {
279
266
  }
280
267
  }
281
268
  })];
282
- }, [data.positions, features, getFillColor, getRadius, mode, radiusScale, selectedFeatureIndexes]);
269
+ }, [sortedData.positions, features, getFillColor, getRadius, mode, radiusScale, selectedFeatureIndexes]);
283
270
  const layers = useDeferredValue(mode === ViewMode ? memoizedLayers.reverse() : memoizedLayers); // draw scatterplot on top of polygons when in ViewMode
284
271
 
285
272
  useEffect(() => {
@@ -322,21 +309,21 @@ export function Scatterplot(_ref) {
322
309
  if (settings.colorEncoding === COLOR_ENCODINGS.OBS && settings.selectedObs && !_.some(settings.labelObs, {
323
310
  name: settings.selectedObs.name
324
311
  })) {
325
- var _obsData$data;
326
- text.push(getLabel(settings.selectedObs, (_obsData$data = obsData.data) === null || _obsData$data === void 0 ? void 0 : _obsData$data[index]));
312
+ var _data$values;
313
+ text.push(getLabel(settings.selectedObs, (_data$values = data.values) === null || _data$values === void 0 ? void 0 : _data$values[getOriginalIndex(index)]));
327
314
  }
328
315
  if (settings.colorEncoding === COLOR_ENCODINGS.VAR && settings.selectedVar) {
329
- var _xData$data;
330
- text.push(getLabel(settings.selectedVar, (_xData$data = xData.data) === null || _xData$data === void 0 ? void 0 : _xData$data[index], true));
316
+ var _data$values2;
317
+ text.push(getLabel(settings.selectedVar, (_data$values2 = data.values) === null || _data$values2 === void 0 ? void 0 : _data$values2[getOriginalIndex(index)], true));
331
318
  }
332
319
  if (settings.labelObs.length) {
333
320
  text.push(..._.map(labelObsData.data, (v, k) => {
334
321
  const labelObs = _.find(settings.labelObs, o => o.name === k);
335
- return getLabel(labelObs, v[index]);
322
+ return getLabel(labelObs, v[getOriginalIndex(index)]);
336
323
  }));
337
324
  }
338
325
  if (!text.length) return;
339
- const grayOut = obsIndices && !obsIndices.has(index);
326
+ const grayOut = sortedObsIndices && !sortedObsIndices.has(index);
340
327
  return {
341
328
  text: text.length ? _.compact(text).join("\n") : null,
342
329
  className: grayOut ? "tooltip-grayout" : "deck-tooltip",
@@ -349,8 +336,7 @@ export function Scatterplot(_ref) {
349
336
  }
350
337
  };
351
338
  };
352
- const isPending = (isRendering || xData.isPending || obsmData.isPending) && !obsmData.isPending;
353
- const error = settings.selectedObsm && ((_obsmData$serverError = obsmData.serverError) === null || _obsmData$serverError === void 0 ? void 0 : _obsmData$serverError.length) || settings.colorEncoding === COLOR_ENCODINGS.VAR && ((_xData$serverError = xData.serverError) === null || _xData$serverError === void 0 ? void 0 : _xData$serverError.length) || settings.colorEncoding === COLOR_ENCODINGS.OBS && ((_obsData$serverError = obsData.serverError) === null || _obsData$serverError === void 0 ? void 0 : _obsData$serverError.length) || settings.labelObs.lengh && ((_labelObsData$serverE = labelObsData.serverError) === null || _labelObsData$serverE === void 0 ? void 0 : _labelObsData$serverE.length);
339
+ const error = settings.selectedObsm && ((_obsmData$serverError = obsmData.serverError) === null || _obsmData$serverError === void 0 ? void 0 : _obsmData$serverError.length) || settings.colorEncoding === COLOR_ENCODINGS.VAR && ((_xData$serverError = xData.serverError) === null || _xData$serverError === void 0 ? void 0 : _xData$serverError.length) || settings.colorEncoding === COLOR_ENCODINGS.OBS && ((_obsData$serverError = obsData.serverError) === null || _obsData$serverError === void 0 ? void 0 : _obsData$serverError.length) || settings.labelObs.length && ((_labelObsData$serverE = labelObsData.serverError) === null || _labelObsData$serverE === void 0 ? void 0 : _labelObsData$serverE.length);
354
340
  return /*#__PURE__*/React.createElement("div", {
355
341
  className: "cherita-container-scatterplot"
356
342
  }, /*#__PURE__*/React.createElement("div", {
@@ -397,13 +383,13 @@ export function Scatterplot(_ref) {
397
383
  className: "cherita-spatial-footer"
398
384
  }, /*#__PURE__*/React.createElement("div", {
399
385
  className: "cherita-toolbox-footer"
400
- }, error && !isPending && /*#__PURE__*/React.createElement(Alert, {
386
+ }, !!error && !isRendering && /*#__PURE__*/React.createElement(Alert, {
401
387
  variant: "danger"
402
388
  }, /*#__PURE__*/React.createElement(FontAwesomeIcon, {
403
389
  icon: faTriangleExclamation
404
390
  }), "\xA0Error loading data"), /*#__PURE__*/React.createElement(Toolbox, {
405
- mode: settings.colorEncoding === COLOR_ENCODINGS.VAR ? (_settings$selectedVar = settings.selectedVar) === null || _settings$selectedVar === void 0 ? void 0 : _settings$selectedVar.name : settings.colorEncoding === COLOR_ENCODINGS.OBS ? (_settings$selectedObs4 = settings.selectedObs) === null || _settings$selectedObs4 === void 0 ? void 0 : _settings$selectedObs4.name : null,
406
- obsLength: parseInt((_obsmData$data = obsmData.data) === null || _obsmData$data === void 0 ? void 0 : _obsmData$data.length),
391
+ mode: settings.colorEncoding === COLOR_ENCODINGS.VAR ? (_settings$selectedVar = settings.selectedVar) === null || _settings$selectedVar === void 0 ? void 0 : _settings$selectedVar.name : settings.colorEncoding === COLOR_ENCODINGS.OBS ? (_settings$selectedObs6 = settings.selectedObs) === null || _settings$selectedObs6 === void 0 ? void 0 : _settings$selectedObs6.name : null,
392
+ obsLength: parseInt((_data$positions = data.positions) === null || _data$positions === void 0 ? void 0 : _data$positions.length),
407
393
  slicedLength: parseInt(slicedLength)
408
394
  })), /*#__PURE__*/React.createElement(Legend, {
409
395
  isCategorical: isCategorical,
@@ -13,6 +13,7 @@ import { useDataset } from "../../context/DatasetContext";
13
13
  import { useSettings, useSettingsDispatch } from "../../context/SettingsContext";
14
14
  import { useFetch } from "../../utils/requests";
15
15
  import { VarDiseaseInfo } from "../var-list/VarItem";
16
+ import { sortMeans, useVarMean } from "../var-list/VarList";
16
17
  export function VarInfo(_ref) {
17
18
  let {
18
19
  varItem
@@ -43,39 +44,6 @@ export function VarInfo(_ref) {
43
44
  data: fetchedData
44
45
  })));
45
46
  }
46
- const useVarMean = function (varKeys) {
47
- let enabled = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
48
- const ENDPOINT = "matrix/mean";
49
- const dataset = useDataset();
50
- const [params, setParams] = useState({
51
- url: dataset.url,
52
- varKeys: _.map(varKeys, v => v.isSet ? {
53
- name: v.name,
54
- indices: v.vars.map(v => v.index)
55
- } : v.index),
56
- // obsIndices:
57
- varNamesCol: dataset.varNamesCol
58
- });
59
- useEffect(() => {
60
- setParams(p => {
61
- return _objectSpread(_objectSpread({}, p), {}, {
62
- varKeys: _.map(varKeys, v => v.isSet ? {
63
- name: v.name,
64
- indices: v.vars.map(v => v.index)
65
- } : v.index)
66
- });
67
- });
68
- }, [varKeys]);
69
- return useFetch(ENDPOINT, params, {
70
- enabled: enabled,
71
- refetchOnMount: false
72
- });
73
- };
74
-
75
- // ensure nulls are lowest values
76
- const sortMeans = (i, means) => {
77
- return means[i.name] || _.min(_.values(means)) - 1;
78
- };
79
47
  export function DiseaseInfo(_ref2) {
80
48
  let {
81
49
  disease,
@@ -14,20 +14,24 @@ import { VarListToolbar } from "./VarListToolbar";
14
14
  import { VarSet } from "./VarSet";
15
15
  import { SELECTION_MODES, VAR_SORT } from "../../constants/constants";
16
16
  import { useDataset } from "../../context/DatasetContext";
17
+ import { useFilteredData } from "../../context/FilterContext";
17
18
  import { useSettings, useSettingsDispatch } from "../../context/SettingsContext";
18
19
  import { LoadingSpinner } from "../../utils/LoadingIndicators";
19
20
  import { useFetch } from "../../utils/requests";
20
- const useVarMean = function (varKeys) {
21
+ export const useVarMean = function (varKeys) {
21
22
  let enabled = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
22
23
  const ENDPOINT = "matrix/mean";
23
24
  const dataset = useDataset();
25
+ const {
26
+ obsIndices
27
+ } = useFilteredData();
24
28
  const [params, setParams] = useState({
25
29
  url: dataset.url,
26
30
  varKeys: _.map(varKeys, v => v.isSet ? {
27
31
  name: v.name,
28
32
  indices: v.vars.map(v => v.index)
29
33
  } : v.index),
30
- // obsIndices:
34
+ obsIndices: obsIndices,
31
35
  varNamesCol: dataset.varNamesCol
32
36
  });
33
37
  useEffect(() => {
@@ -36,10 +40,11 @@ const useVarMean = function (varKeys) {
36
40
  varKeys: _.map(varKeys, v => v.isSet ? {
37
41
  name: v.name,
38
42
  indices: v.vars.map(v => v.index)
39
- } : v.index)
43
+ } : v.index),
44
+ obsIndices: obsIndices
40
45
  });
41
46
  });
42
- }, [varKeys]);
47
+ }, [obsIndices, varKeys]);
43
48
  return useFetch(ENDPOINT, params, {
44
49
  enabled: enabled,
45
50
  refetchOnMount: false
@@ -47,7 +52,7 @@ const useVarMean = function (varKeys) {
47
52
  };
48
53
 
49
54
  // ensure nulls are lowest values
50
- const sortMeans = (i, means) => {
55
+ export const sortMeans = (i, means) => {
51
56
  return means[i.name] || _.min(_.values(means)) - 1;
52
57
  };
53
58
  export function VarNamesList(_ref) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@haniffalab/cherita-react",
3
- "version": "1.3.0-dev.2025-06-05.2b7d4704",
3
+ "version": "1.3.0-dev.2025-06-06.9f7ff5ad",
4
4
  "author": "Haniffa Lab",
5
5
  "license": "MIT",
6
6
  "keywords": [
@@ -127,5 +127,5 @@
127
127
  "url": "https://github.com/haniffalab/cherita-react/issues"
128
128
  },
129
129
  "homepage": "https://github.com/haniffalab/cherita-react#readme",
130
- "prereleaseSha": "2b7d4704cf12e0c0f474797aeb9b6b76384f22c2"
130
+ "prereleaseSha": "9f7ff5ad72d373bccc11058ca146ba13811cfa70"
131
131
  }