@haniffalab/cherita-react 1.0.0-dev.2025-03-28.876db178 → 1.0.0-dev.2025-04-01.e61c9d78

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.
Files changed (33) hide show
  1. package/dist/cjs/components/full-page/FullPage.js +26 -17
  2. package/dist/cjs/components/obs-list/ObsItem.js +38 -31
  3. package/dist/cjs/components/obs-list/ObsList.js +40 -13
  4. package/dist/cjs/components/obs-list/ObsToolbar.js +3 -44
  5. package/dist/cjs/components/obsm-list/ObsmList.js +7 -4
  6. package/dist/cjs/components/scatterplot/Scatterplot.js +2 -2
  7. package/dist/cjs/components/scatterplot/SpatialControls.js +32 -32
  8. package/dist/cjs/components/scatterplot/Toolbox.js +40 -10
  9. package/dist/cjs/components/search-bar/SearchBar.js +18 -2
  10. package/dist/cjs/components/var-list/VarList.js +36 -17
  11. package/dist/cjs/components/var-list/VarListToolbar.js +14 -11
  12. package/dist/cjs/components/var-list/VarSet.js +3 -2
  13. package/dist/cjs/utils/Skeleton.js +19 -0
  14. package/dist/css/cherita.css +144 -168
  15. package/dist/css/cherita.css.map +1 -1
  16. package/dist/esm/components/full-page/FullPage.js +27 -18
  17. package/dist/esm/components/obs-list/ObsItem.js +40 -33
  18. package/dist/esm/components/obs-list/ObsList.js +41 -14
  19. package/dist/esm/components/obs-list/ObsToolbar.js +4 -45
  20. package/dist/esm/components/obsm-list/ObsmList.js +8 -5
  21. package/dist/esm/components/scatterplot/Scatterplot.js +3 -3
  22. package/dist/esm/components/scatterplot/SpatialControls.js +34 -34
  23. package/dist/esm/components/scatterplot/Toolbox.js +40 -10
  24. package/dist/esm/components/search-bar/SearchBar.js +20 -4
  25. package/dist/esm/components/var-list/VarList.js +37 -18
  26. package/dist/esm/components/var-list/VarListToolbar.js +13 -10
  27. package/dist/esm/components/var-list/VarSet.js +5 -4
  28. package/dist/esm/utils/Skeleton.js +12 -0
  29. package/package.json +2 -2
  30. package/scss/cherita.scss +15 -70
  31. package/scss/components/accordions.scss +32 -0
  32. package/scss/components/layouts.scss +1 -1
  33. package/scss/components/lists.scss +14 -0
@@ -38,6 +38,7 @@ function FullPage(_ref) {
38
38
  const [showObsm, setShowObsm] = (0, _react.useState)(false);
39
39
  const [showVars, setShowVars] = (0, _react.useState)(false);
40
40
  const [showControls, setShowControls] = (0, _react.useState)(false);
41
+ const [showModal, setShowModal] = (0, _react.useState)(false);
41
42
  (0, _react.useEffect)(() => {
42
43
  const updateDimensions = () => {
43
44
  if (appRef.current) {
@@ -65,14 +66,12 @@ function FullPage(_ref) {
65
66
  style: {
66
67
  height: appDimensions.height
67
68
  }
68
- }, /*#__PURE__*/_react.default.createElement(_DatasetContext.DatasetProvider, props, /*#__PURE__*/_react.default.createElement("div", {
69
- className: "row g-0"
70
- }, /*#__PURE__*/_react.default.createElement("div", {
71
- className: "cherita-app-obs modern-scrollbars border-end h-100"
72
- }, /*#__PURE__*/_react.default.createElement(_ObsList.ObsColsList, props)), /*#__PURE__*/_react.default.createElement("div", {
73
- className: "cherita-app-plot"
74
- }, /*#__PURE__*/_react.default.createElement("div", {
75
- className: "position-relative"
69
+ }, /*#__PURE__*/_react.default.createElement(_DatasetContext.DatasetProvider, props, /*#__PURE__*/_react.default.createElement(_reactBootstrap.Container, {
70
+ fluid: true,
71
+ className: "d-flex g-0",
72
+ style: {
73
+ height: appDimensions.height
74
+ }
76
75
  }, /*#__PURE__*/_react.default.createElement(_reactBootstrap.Navbar, {
77
76
  expand: "sm",
78
77
  bg: "primary",
@@ -96,18 +95,28 @@ function FullPage(_ref) {
96
95
  className: "d-flex"
97
96
  }, /*#__PURE__*/_react.default.createElement(_reactBootstrap.Nav.Item, null, /*#__PURE__*/_react.default.createElement(_reactBootstrap.Nav.Link, {
98
97
  onClick: () => setShowControls(true)
99
- }, "Controls"))))))), children), /*#__PURE__*/_react.default.createElement("div", {
100
- className: "cherita-app-var"
101
- }, /*#__PURE__*/_react.default.createElement(_reactBootstrap.Card, {
102
- className: "cherita-app-features"
103
- }, /*#__PURE__*/_react.default.createElement(_reactBootstrap.Card.Body, null, /*#__PURE__*/_react.default.createElement(_SearchBar.SearchBar, {
98
+ }, "Controls")))))), /*#__PURE__*/_react.default.createElement("div", {
99
+ className: "cherita-app-obs modern-scrollbars border-end h-100"
100
+ }, /*#__PURE__*/_react.default.createElement(_ObsList.ObsColsList, props)), /*#__PURE__*/_react.default.createElement("div", {
101
+ className: "cherita-app-canvas flex-grow-1"
102
+ }, children), /*#__PURE__*/_react.default.createElement("div", {
103
+ className: "cherita-app-sidebar p-3"
104
+ }, /*#__PURE__*/_react.default.createElement(_reactBootstrap.Card, null, /*#__PURE__*/_react.default.createElement(_reactBootstrap.Card.Body, {
105
+ className: "d-flex flex-column p-0"
106
+ }, /*#__PURE__*/_react.default.createElement("div", {
107
+ className: "sidebar-features modern-scrollbars"
108
+ }, /*#__PURE__*/_react.default.createElement(_SearchBar.SearchBar, {
104
109
  searchDiseases: true,
105
110
  searchVar: true
106
111
  }), /*#__PURE__*/_react.default.createElement(_VarList.VarNamesList, {
107
112
  mode: varMode
108
- })))), /*#__PURE__*/_react.default.createElement("div", {
109
- className: "col"
110
- }, /*#__PURE__*/_react.default.createElement(_offcanvas.OffcanvasObs, {
113
+ })))))), /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement(_reactBootstrap.Modal, {
114
+ show: showModal,
115
+ onHide: () => setShowModal(false),
116
+ centered: true
117
+ }, /*#__PURE__*/_react.default.createElement(_reactBootstrap.Modal.Header, {
118
+ closeButton: true
119
+ }), /*#__PURE__*/_react.default.createElement(_reactBootstrap.Modal.Body, null)), /*#__PURE__*/_react.default.createElement(_offcanvas.OffcanvasObs, {
111
120
  show: showObs,
112
121
  handleClose: () => setShowObs(false)
113
122
  }), /*#__PURE__*/_react.default.createElement(_offcanvas.OffcanvasVars, {
@@ -120,7 +129,7 @@ function FullPage(_ref) {
120
129
  }), /*#__PURE__*/_react.default.createElement(_offcanvas.OffcanvasObsm, {
121
130
  show: showObsm,
122
131
  handleClose: () => setShowObsm(false)
123
- })))));
132
+ }))));
124
133
  }
125
134
  function FullPageScatterplot(props) {
126
135
  return /*#__PURE__*/_react.default.createElement(FullPage, props, /*#__PURE__*/_react.default.createElement(_Scatterplot.Scatterplot, null));
@@ -10,7 +10,6 @@ var _material = require("@mui/material");
10
10
  var _xCharts = require("@mui/x-charts");
11
11
  var _lodash = _interopRequireDefault(require("lodash"));
12
12
  var _reactBootstrap = require("react-bootstrap");
13
- var _ObsToolbar = require("./ObsToolbar");
14
13
  var _constants = require("../../constants/constants");
15
14
  var _DatasetContext = require("../../context/DatasetContext");
16
15
  var _FilterContext = require("../../context/FilterContext");
@@ -21,6 +20,7 @@ var _requests = require("../../utils/requests");
21
20
  var _string = require("../../utils/string");
22
21
  var _VirtualizedList = require("../../utils/VirtualizedList");
23
22
  var _zarrData = require("../../utils/zarrData");
23
+ var _ObsToolbar = require("./ObsToolbar");
24
24
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
25
25
  function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
26
26
  function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
@@ -305,13 +305,13 @@ function CategoricalObs(_ref2) {
305
305
  }, [dataset.colorEncoding, filteredObsData?.pct, filteredObsData?.value_counts, isSliced, obs.codes, obs.omit, obs.value_counts, obs.values, obsHistograms.fetchedData, obsHistograms.isPending, totalCounts]);
306
306
  showColor &= dataset.colorEncoding === _constants.COLOR_ENCODINGS.OBS;
307
307
  return /*#__PURE__*/_react.default.createElement(_reactBootstrap.ListGroup, {
308
- variant: "flush"
309
- }, /*#__PURE__*/_react.default.createElement(_reactBootstrap.ListGroup.Item, null, /*#__PURE__*/_react.default.createElement(_ObsToolbar.ObsToolbar, {
308
+ variant: "flush",
309
+ className: "cherita-list"
310
+ }, /*#__PURE__*/_react.default.createElement(_reactBootstrap.ListGroup.Item, {
311
+ className: "cherita-list-item-unstyled"
312
+ }, /*#__PURE__*/_react.default.createElement(_ObsToolbar.ObsToolbar, {
310
313
  item: obs,
311
- onToggleAllObs: toggleAll,
312
- onToggleLabel: toggleLabel,
313
- onToggleSlice: toggleSlice,
314
- onToggleColor: toggleColor
314
+ onToggleAllObs: toggleAll
315
315
  })), /*#__PURE__*/_react.default.createElement(_VirtualizedList.VirtualizedList, {
316
316
  getDataAtIndex: getDataAtIndex,
317
317
  count: obs.values.length,
@@ -340,31 +340,25 @@ function ObsContinuousStats(_ref3) {
340
340
  } = (0, _requests.useFetch)(ENDPOINT, params);
341
341
 
342
342
  // @TODO: fix width issue when min/max/etc values are too large
343
- return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("div", {
344
- className: "d-flex justify-content-between mt-3 align-items-center"
345
- }, /*#__PURE__*/_react.default.createElement(_reactBootstrap.Table, {
346
- size: "sm",
347
- className: "obs-continuous-stats",
348
- striped: true
349
- }, /*#__PURE__*/_react.default.createElement("tbody", null, /*#__PURE__*/_react.default.createElement("tr", null, /*#__PURE__*/_react.default.createElement("td", null, "Min"), /*#__PURE__*/_react.default.createElement("td", {
350
- className: "text-end"
351
- }, (0, _string.formatNumerical)(obs.min, _string.FORMATS.EXPONENTIAL))), /*#__PURE__*/_react.default.createElement("tr", null, /*#__PURE__*/_react.default.createElement("td", null, "Max"), /*#__PURE__*/_react.default.createElement("td", {
352
- className: "text-end"
353
- }, (0, _string.formatNumerical)(obs.max, _string.FORMATS.EXPONENTIAL))))), /*#__PURE__*/_react.default.createElement(_reactBootstrap.Table, {
354
- size: "sm",
355
- className: "obs-continuous-stats",
356
- striped: true
357
- }, /*#__PURE__*/_react.default.createElement("tbody", null, /*#__PURE__*/_react.default.createElement("tr", null, /*#__PURE__*/_react.default.createElement("td", null, "Mean"), /*#__PURE__*/_react.default.createElement("td", {
358
- className: "text-end"
359
- }, (0, _string.formatNumerical)(obs.mean, _string.FORMATS.EXPONENTIAL))), /*#__PURE__*/_react.default.createElement("tr", null, /*#__PURE__*/_react.default.createElement("td", null, "Median"), /*#__PURE__*/_react.default.createElement("td", {
360
- className: "text-end"
361
- }, (0, _string.formatNumerical)(obs.median, _string.FORMATS.EXPONENTIAL))))), isPending && /*#__PURE__*/_react.default.createElement(_LoadingIndicators.LoadingLinear, null), !isPending && !serverError && /*#__PURE__*/_react.default.createElement("div", {
343
+ return /*#__PURE__*/_react.default.createElement(_reactBootstrap.ListGroup, {
344
+ variant: "flush",
345
+ className: "cherita-list"
346
+ }, /*#__PURE__*/_react.default.createElement(_reactBootstrap.ListGroup.Item, {
347
+ className: "obs-item"
348
+ }, /*#__PURE__*/_react.default.createElement("h5", {
349
+ className: "mb-2"
350
+ }, "Statistics"), /*#__PURE__*/_react.default.createElement("div", {
351
+ className: "row"
352
+ }, /*#__PURE__*/_react.default.createElement("div", {
353
+ className: "col-md-7"
354
+ }, /*#__PURE__*/_react.default.createElement("p", {
355
+ className: "mb-1 small"
356
+ }, "Distribution of continuous values"), isPending && /*#__PURE__*/_react.default.createElement(_LoadingIndicators.LoadingLinear, null), !isPending && !serverError && /*#__PURE__*/_react.default.createElement("div", {
362
357
  className: "obs-distribution"
363
358
  }, /*#__PURE__*/_react.default.createElement(_xCharts.SparkLineChart, {
364
359
  data: fetchedData.kde_values[1],
365
360
  showHighlight: true,
366
- showTooltip: true // throws Maximum update depth exceeded error. Documented here: https://github.com/mui/mui-x/issues/13450
367
- ,
361
+ showTooltip: true,
368
362
  margin: {
369
363
  top: 10,
370
364
  right: 20,
@@ -381,7 +375,17 @@ function ObsContinuousStats(_ref3) {
381
375
  className: "feature-histogram-tooltip"
382
376
  }
383
377
  }
384
- }))));
378
+ }))), /*#__PURE__*/_react.default.createElement("div", {
379
+ className: "col-md-5 d-flex flex-column text-end"
380
+ }, /*#__PURE__*/_react.default.createElement("div", {
381
+ className: "d-flex justify-content-between"
382
+ }, /*#__PURE__*/_react.default.createElement("span", null, "Min"), " ", /*#__PURE__*/_react.default.createElement("span", null, (0, _string.formatNumerical)(obs.min, _string.FORMATS.EXPONENTIAL))), /*#__PURE__*/_react.default.createElement("div", {
383
+ className: "d-flex justify-content-between"
384
+ }, /*#__PURE__*/_react.default.createElement("span", null, "Max"), " ", /*#__PURE__*/_react.default.createElement("span", null, (0, _string.formatNumerical)(obs.max, _string.FORMATS.EXPONENTIAL))), /*#__PURE__*/_react.default.createElement("div", {
385
+ className: "d-flex justify-content-between"
386
+ }, /*#__PURE__*/_react.default.createElement("span", null, "Mean"), " ", /*#__PURE__*/_react.default.createElement("span", null, (0, _string.formatNumerical)(obs.mean, _string.FORMATS.EXPONENTIAL))), /*#__PURE__*/_react.default.createElement("div", {
387
+ className: "d-flex justify-content-between"
388
+ }, /*#__PURE__*/_react.default.createElement("span", null, "Median"), " ", /*#__PURE__*/_react.default.createElement("span", null, (0, _string.formatNumerical)(obs.median, _string.FORMATS.EXPONENTIAL)))))));
385
389
  }
386
390
  function ContinuousObs(_ref4) {
387
391
  let {
@@ -465,8 +469,11 @@ function ContinuousObs(_ref4) {
465
469
  };
466
470
  };
467
471
  return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, isPending && /*#__PURE__*/_react.default.createElement(_LoadingIndicators.LoadingLinear, null), !serverError && updatedObs && /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_reactBootstrap.ListGroup, {
468
- variant: "flush"
469
- }, /*#__PURE__*/_react.default.createElement(_reactBootstrap.ListGroup.Item, null, /*#__PURE__*/_react.default.createElement(_ObsToolbar.ObsToolbar, {
472
+ variant: "flush",
473
+ className: "cherita-list"
474
+ }, /*#__PURE__*/_react.default.createElement(_reactBootstrap.ListGroup.Item, {
475
+ className: "cherita-list-item-unstyled"
476
+ }, /*#__PURE__*/_react.default.createElement(_ObsToolbar.ObsToolbar, {
470
477
  item: obs,
471
478
  onToggleAllObs: toggleAll,
472
479
  onToggleLabel: toggleLabel,
@@ -7,16 +7,19 @@ exports.ObsColsList = ObsColsList;
7
7
  var _react = _interopRequireWildcard(require("react"));
8
8
  var _freeSolidSvgIcons = require("@fortawesome/free-solid-svg-icons");
9
9
  var _reactFontawesome = require("@fortawesome/react-fontawesome");
10
+ var _Comment = _interopRequireDefault(require("@mui/icons-material/Comment"));
11
+ var _JoinInner = _interopRequireDefault(require("@mui/icons-material/JoinInner"));
12
+ var _WaterDrop = _interopRequireDefault(require("@mui/icons-material/WaterDrop"));
10
13
  var _lodash = _interopRequireDefault(require("lodash"));
11
14
  var _reactBootstrap = require("react-bootstrap");
12
15
  var _Accordion = _interopRequireDefault(require("react-bootstrap/Accordion"));
13
16
  var _AccordionButton = require("react-bootstrap/AccordionButton");
14
17
  var _AccordionContext = _interopRequireDefault(require("react-bootstrap/AccordionContext"));
15
- var _ObsItem = require("./ObsItem");
16
18
  var _constants = require("../../constants/constants");
17
19
  var _DatasetContext = require("../../context/DatasetContext");
18
20
  var _LoadingIndicators = require("../../utils/LoadingIndicators");
19
21
  var _requests = require("../../utils/requests");
22
+ var _ObsItem = require("./ObsItem");
20
23
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
21
24
  function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
22
25
  function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
@@ -110,6 +113,18 @@ function ObsColsList(_ref2) {
110
113
  }), "name"));
111
114
  }
112
115
  }, [fetchedData, isPending, obsGroups, serverError, enableGroups]);
116
+ (0, _react.useEffect)(() => {
117
+ if (obsCols && Object.keys(expandedItems).length === 0) {
118
+ const initialExpanded = Object.keys(obsCols).reduce((acc, key) => {
119
+ acc[key] = false;
120
+ return acc;
121
+ }, {});
122
+ if (active && obsCols[active]) {
123
+ initialExpanded[active] = true;
124
+ }
125
+ setExpandedItems(initialExpanded);
126
+ }
127
+ }, [obsCols, expandedItems, active]);
113
128
 
114
129
  // @TODO: fix re-rendering performance issue
115
130
  (0, _react.useEffect)(() => {
@@ -237,23 +252,33 @@ function ObsColsList(_ref2) {
237
252
  const inSliceObs = dataset.sliceBy.obs && dataset.selectedObs?.name === item.name;
238
253
  const isColorEncoding = dataset.colorEncoding === _constants.COLOR_ENCODINGS.OBS && dataset.selectedObs?.name === item.name;
239
254
  return /*#__PURE__*/_react.default.createElement("div", {
255
+ className: "accordion-item",
240
256
  key: item.name
241
257
  }, /*#__PURE__*/_react.default.createElement(ObsAccordionToggle, {
242
258
  eventKey: item.name,
243
259
  handleAccordionToggle: handleAccordionToggle
244
- }, /*#__PURE__*/_react.default.createElement("div", null, item.name), /*#__PURE__*/_react.default.createElement("div", null, inLabelObs && /*#__PURE__*/_react.default.createElement(_reactFontawesome.FontAwesomeIcon, {
245
- className: "mx-1",
246
- icon: _freeSolidSvgIcons.faListOl,
247
- title: "In tooltip"
248
- }), inSliceObs && /*#__PURE__*/_react.default.createElement(_reactFontawesome.FontAwesomeIcon, {
249
- className: "mx-1",
250
- icon: _freeSolidSvgIcons.faScissors,
260
+ }, /*#__PURE__*/_react.default.createElement("div", null, item.name), /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement("span", {
261
+ className: `mx-1 cursor-pointer ${inLabelObs ? "active-icon" : "text-muted opacity-50"}`,
262
+ onClick: event => {
263
+ event.stopPropagation();
264
+ toggleLabel(item);
265
+ },
266
+ title: "Add to tooltip"
267
+ }, /*#__PURE__*/_react.default.createElement(_Comment.default, null)), /*#__PURE__*/_react.default.createElement("span", {
268
+ className: `mx-1 cursor-pointer ${inSliceObs ? "active-icon" : "text-muted opacity-50"}`,
269
+ onClick: event => {
270
+ event.stopPropagation();
271
+ toggleSlice(item);
272
+ },
251
273
  title: "Filter applied"
252
- }), isColorEncoding && /*#__PURE__*/_react.default.createElement(_reactFontawesome.FontAwesomeIcon, {
253
- className: "mx-1",
254
- icon: _freeSolidSvgIcons.faDroplet,
274
+ }, /*#__PURE__*/_react.default.createElement(_JoinInner.default, null)), /*#__PURE__*/_react.default.createElement("span", {
275
+ className: `mx-1 cursor-pointer ${isColorEncoding ? "active-icon" : "text-muted opacity-50"}`,
276
+ onClick: event => {
277
+ event.stopPropagation();
278
+ toggleColor(item);
279
+ },
255
280
  title: "Is color encoding"
256
- }))), /*#__PURE__*/_react.default.createElement(_Accordion.default.Collapse, {
281
+ }, /*#__PURE__*/_react.default.createElement(_WaterDrop.default, null)))), /*#__PURE__*/_react.default.createElement(_Accordion.default.Collapse, {
257
282
  eventKey: item.name
258
283
  }, /*#__PURE__*/_react.default.createElement("div", {
259
284
  className: "obs-accordion-body"
@@ -303,7 +328,9 @@ function ObsColsList(_ref2) {
303
328
  alwaysOpen: true
304
329
  }, groupList) : _lodash.default.map(_lodash.default.sortBy(obsCols, o => _lodash.default.lowerCase(o.name)), item => obsItem(item));
305
330
  if (!serverError) {
306
- return /*#__PURE__*/_react.default.createElement("div", null, isPending && /*#__PURE__*/_react.default.createElement(_LoadingIndicators.LoadingSpinner, null), !isPending && !!obsCols && !_lodash.default.size(obsCols) ? /*#__PURE__*/_react.default.createElement(_reactBootstrap.Alert, {
331
+ return /*#__PURE__*/_react.default.createElement("div", {
332
+ className: "position-relative h-100"
333
+ }, isPending ? /*#__PURE__*/_react.default.createElement(_LoadingIndicators.LoadingSpinner, null) : !!obsCols && !_lodash.default.size(obsCols) ? /*#__PURE__*/_react.default.createElement(_reactBootstrap.Alert, {
307
334
  variant: "danger"
308
335
  }, "No observations found.") : /*#__PURE__*/_react.default.createElement(_Accordion.default, {
309
336
  flush: true,
@@ -5,61 +5,20 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.ObsToolbar = ObsToolbar;
7
7
  var _react = _interopRequireDefault(require("react"));
8
- var _freeSolidSvgIcons = require("@fortawesome/free-solid-svg-icons");
9
- var _reactFontawesome = require("@fortawesome/react-fontawesome");
10
- var _lodash = _interopRequireDefault(require("lodash"));
11
8
  var _reactBootstrap = require("react-bootstrap");
12
- var _constants = require("../../constants/constants");
13
- var _DatasetContext = require("../../context/DatasetContext");
14
9
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
15
10
  function ObsToolbar(_ref) {
16
11
  let {
17
12
  item,
18
13
  showToggleAllObs = true,
19
- showLabel = true,
20
- showSlice = true,
21
- showColor = true,
22
- onToggleAllObs,
23
- onToggleLabel,
24
- onToggleSlice,
25
- onToggleColor
14
+ onToggleAllObs
26
15
  } = _ref;
27
- const dataset = (0, _DatasetContext.useDataset)();
28
16
  const allToggledOn = !item.omit.length;
29
- const inLabelObs = _lodash.default.some(dataset.labelObs, i => i.name === item.name);
30
- const inSliceObs = dataset.sliceBy.obs && dataset.selectedObs?.name === item.name;
31
- const isColorEncoding = dataset.colorEncoding === _constants.COLOR_ENCODINGS.OBS && dataset.selectedObs?.name === item.name;
32
- return /*#__PURE__*/_react.default.createElement("div", {
33
- className: "d-flex align-items-center"
34
- }, /*#__PURE__*/_react.default.createElement("div", {
35
- className: "flex-grow-1"
36
- }, showToggleAllObs && /*#__PURE__*/_react.default.createElement(_reactBootstrap.Form.Check, {
37
- // prettier-ignore
17
+ return showToggleAllObs && /*#__PURE__*/_react.default.createElement(_reactBootstrap.Form.Check, {
38
18
  type: "switch",
39
19
  id: "custom-switch",
40
20
  label: "Toggle all",
41
21
  checked: allToggledOn,
42
22
  onChange: onToggleAllObs
43
- })), /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement(_reactBootstrap.ButtonGroup, null, showLabel && /*#__PURE__*/_react.default.createElement(_reactBootstrap.Button, {
44
- variant: inLabelObs ? "primary" : "outline-primary",
45
- size: "sm",
46
- onClick: onToggleLabel,
47
- title: "Add to tooltip"
48
- }, /*#__PURE__*/_react.default.createElement(_reactFontawesome.FontAwesomeIcon, {
49
- icon: _freeSolidSvgIcons.faListOl
50
- })), showSlice && /*#__PURE__*/_react.default.createElement(_reactBootstrap.Button, {
51
- variant: inSliceObs ? "primary" : "outline-primary",
52
- size: "sm",
53
- onClick: onToggleSlice,
54
- title: "Filter to selected"
55
- }, /*#__PURE__*/_react.default.createElement(_reactFontawesome.FontAwesomeIcon, {
56
- icon: _freeSolidSvgIcons.faScissors
57
- })), showColor && /*#__PURE__*/_react.default.createElement(_reactBootstrap.Button, {
58
- variant: isColorEncoding ? "primary" : "outline-primary",
59
- size: "sm",
60
- onClick: onToggleColor,
61
- title: "Set as color encoding"
62
- }, /*#__PURE__*/_react.default.createElement(_reactFontawesome.FontAwesomeIcon, {
63
- icon: _freeSolidSvgIcons.faDroplet
64
- })))));
23
+ });
65
24
  }
@@ -7,8 +7,8 @@ exports.ObsmKeysList = ObsmKeysList;
7
7
  var _react = _interopRequireWildcard(require("react"));
8
8
  var _reactBootstrap = require("react-bootstrap");
9
9
  var _DatasetContext = require("../../context/DatasetContext");
10
- var _LoadingIndicators = require("../../utils/LoadingIndicators");
11
10
  var _requests = require("../../utils/requests");
11
+ var _Skeleton = require("../../utils/Skeleton");
12
12
  function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
13
13
  function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
14
14
  function ObsmKeysList() {
@@ -58,13 +58,16 @@ function ObsmKeysList() {
58
58
  }, item);
59
59
  });
60
60
  if (!serverError) {
61
- return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, isPending && /*#__PURE__*/_react.default.createElement(_LoadingIndicators.LoadingSpinner, null), /*#__PURE__*/_react.default.createElement(_reactBootstrap.DropdownButton, {
61
+ if (isPending) {
62
+ return /*#__PURE__*/_react.default.createElement(_Skeleton.ObsmKeysListBtn, null);
63
+ }
64
+ return /*#__PURE__*/_react.default.createElement(_reactBootstrap.DropdownButton, {
62
65
  as: _reactBootstrap.ButtonGroup,
63
66
  title: dataset.selectedObsm || "Select an embedding",
64
- variant: dataset.selectedObsm ? "primary" : "outline-primary",
67
+ variant: dataset.selectedObsm ? "primary" : "warning",
65
68
  id: "bg-nested-dropdown",
66
69
  size: "sm"
67
- }, obsmList));
70
+ }, /*#__PURE__*/_react.default.createElement(_reactBootstrap.Dropdown.Header, null, "Embeddings"), obsmList);
68
71
  } else {
69
72
  return /*#__PURE__*/_react.default.createElement(_reactBootstrap.OverlayTrigger, {
70
73
  placement: "top",
@@ -13,8 +13,6 @@ var _editModes = require("@nebula.gl/edit-modes");
13
13
  var _layers2 = require("@nebula.gl/layers");
14
14
  var _lodash = _interopRequireDefault(require("lodash"));
15
15
  var _reactBootstrap = require("react-bootstrap");
16
- var _SpatialControls = require("./SpatialControls");
17
- var _Toolbox = require("./Toolbox");
18
16
  var _constants = require("../../constants/constants");
19
17
  var _DatasetContext = require("../../context/DatasetContext");
20
18
  var _FilterContext = require("../../context/FilterContext");
@@ -25,6 +23,8 @@ var _Legend = require("../../utils/Legend");
25
23
  var _LoadingIndicators = require("../../utils/LoadingIndicators");
26
24
  var _string = require("../../utils/string");
27
25
  var _zarrData = require("../../utils/zarrData");
26
+ var _SpatialControls = require("./SpatialControls");
27
+ var _Toolbox = require("./Toolbox");
28
28
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
29
29
  function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
30
30
  function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
@@ -12,10 +12,9 @@ var _editModes = require("@nebula.gl/edit-modes");
12
12
  var _Button = _interopRequireDefault(require("react-bootstrap/Button"));
13
13
  var _ButtonGroup = _interopRequireDefault(require("react-bootstrap/ButtonGroup"));
14
14
  var _Dropdown = _interopRequireDefault(require("react-bootstrap/Dropdown"));
15
- var _DropdownButton = _interopRequireDefault(require("react-bootstrap/DropdownButton"));
16
- var _ScatterplotControls = require("./ScatterplotControls");
17
15
  var _DatasetContext = require("../../context/DatasetContext");
18
16
  var _offcanvas = require("../offcanvas");
17
+ var _ScatterplotControls = require("./ScatterplotControls");
19
18
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
20
19
  function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
21
20
  function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
@@ -62,13 +61,8 @@ function SpatialControls(_ref) {
62
61
  features: []
63
62
  });
64
63
  };
65
- const polygonControls = /*#__PURE__*/_react.default.createElement("div", {
66
- className: "mt-2"
67
- }, /*#__PURE__*/_react.default.createElement(_ButtonGroup.default, {
68
- vertical: true,
69
- className: "w-100"
70
- }, /*#__PURE__*/_react.default.createElement(_Button.default, {
71
- variant: dataset.sliceBy.polygons ? "primary" : "outline-primary",
64
+ const polygonControls = /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_Button.default, {
65
+ active: dataset.sliceBy.polygons,
72
66
  title: "Filter data with polygons",
73
67
  onClick: () => {
74
68
  setMode(() => _editModes.ViewMode);
@@ -77,7 +71,6 @@ function SpatialControls(_ref) {
77
71
  });
78
72
  }
79
73
  }, /*#__PURE__*/_react.default.createElement(_iconsMaterial.JoinInner, null)), /*#__PURE__*/_react.default.createElement(_Button.default, {
80
- variant: "outline-primary",
81
74
  title: "Delete selected polygons",
82
75
  onClick: () => {
83
76
  const newFeatures = features.features.filter((_f, i) => !selectedFeatureIndexes.includes(i));
@@ -89,12 +82,12 @@ function SpatialControls(_ref) {
89
82
  disabled: !selectedFeatureIndexes.length
90
83
  }, /*#__PURE__*/_react.default.createElement(_reactFontawesome.FontAwesomeIcon, {
91
84
  icon: _freeSolidSvgIcons.faTrash
92
- }))));
85
+ })));
93
86
  return /*#__PURE__*/_react.default.createElement("div", {
94
87
  className: "cherita-spatial-controls"
95
88
  }, /*#__PURE__*/_react.default.createElement(_ButtonGroup.default, {
96
89
  vertical: true,
97
- className: "w-100"
90
+ className: "w-100 mb-1"
98
91
  }, /*#__PURE__*/_react.default.createElement(_Button.default, {
99
92
  onClick: increaseZoom,
100
93
  title: "Increase zoom"
@@ -111,37 +104,44 @@ function SpatialControls(_ref) {
111
104
  }, /*#__PURE__*/_react.default.createElement(_reactFontawesome.FontAwesomeIcon, {
112
105
  icon: _freeSolidSvgIcons.faCrosshairs
113
106
  })), /*#__PURE__*/_react.default.createElement(_Button.default, {
107
+ onClick: handleShowControls
108
+ }, /*#__PURE__*/_react.default.createElement(_reactFontawesome.FontAwesomeIcon, {
109
+ icon: _freeSolidSvgIcons.faSliders
110
+ }))), /*#__PURE__*/_react.default.createElement(_ButtonGroup.default, {
111
+ vertical: true,
112
+ className: "w-100"
113
+ }, /*#__PURE__*/_react.default.createElement(_Button.default, {
114
114
  onClick: () => setMode(() => _editModes.ViewMode),
115
115
  title: "Set dragging mode",
116
- variant: mode === _editModes.ViewMode ? "primary" : "outline-primary"
116
+ active: mode === _editModes.ViewMode
117
117
  }, /*#__PURE__*/_react.default.createElement(_reactFontawesome.FontAwesomeIcon, {
118
118
  icon: _freeSolidSvgIcons.faHand
119
- })), /*#__PURE__*/_react.default.createElement(_DropdownButton.default, {
119
+ })), /*#__PURE__*/_react.default.createElement(_Dropdown.default, {
120
120
  as: _ButtonGroup.default,
121
- title: /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_reactFontawesome.FontAwesomeIcon, {
122
- icon: _freeSolidSvgIcons.faDrawPolygon
123
- })),
124
- drop: "end",
125
- id: "bg-vertical-dropdown-1",
126
121
  className: "caret-off",
122
+ drop: "end",
127
123
  onSelect: onSelect
128
- }, /*#__PURE__*/_react.default.createElement(_Dropdown.default.Header, null, "Selection tools"), /*#__PURE__*/_react.default.createElement(_Dropdown.default.Item, {
129
- eventKey: "DrawPolygonMode"
130
- }, "Draw a polygon"), /*#__PURE__*/_react.default.createElement(_Dropdown.default.Item, {
124
+ }, /*#__PURE__*/_react.default.createElement(_Dropdown.default.Toggle, {
125
+ id: "dropdown-autoclose-outside",
126
+ className: `caret-off ${mode === _editModes.DrawPolygonByDraggingMode || mode === _editModes.ModifyMode ? "active" : ""}`
127
+ }, /*#__PURE__*/_react.default.createElement(_reactFontawesome.FontAwesomeIcon, {
128
+ icon: _freeSolidSvgIcons.faDrawPolygon
129
+ })), /*#__PURE__*/_react.default.createElement(_Dropdown.default.Menu, null, /*#__PURE__*/_react.default.createElement(_Dropdown.default.Header, null, "Polygon tools"), /*#__PURE__*/_react.default.createElement(_Dropdown.default.Item, {
131
130
  eventKey: "DrawPolygonByDraggingMode"
132
- }, "Draw a Polygon by Dragging"), /*#__PURE__*/_react.default.createElement(_Dropdown.default.Item, {
131
+ }, /*#__PURE__*/_react.default.createElement(_reactFontawesome.FontAwesomeIcon, {
132
+ icon: _freeSolidSvgIcons.faDrawPolygon,
133
+ className: "nav-icon"
134
+ }), "Draw a polygon"), /*#__PURE__*/_react.default.createElement(_Dropdown.default.Item, {
133
135
  eventKey: "ModifyMode"
134
- }, "Modify polygons"), /*#__PURE__*/_react.default.createElement(_Dropdown.default.Item, {
135
- eventKey: "ViewMode"
136
- }, "Viewing mode"), /*#__PURE__*/_react.default.createElement(_Dropdown.default.Item, {
137
- onClick: deleteFeatures
138
136
  }, /*#__PURE__*/_react.default.createElement(_reactFontawesome.FontAwesomeIcon, {
139
- icon: _freeSolidSvgIcons.faTrash
140
- }), " Delete polygons")), /*#__PURE__*/_react.default.createElement(_Button.default, {
141
- onClick: handleShowControls
137
+ icon: _freeSolidSvgIcons.faPen,
138
+ className: "nav-icon"
139
+ }), "Modify polygons"), /*#__PURE__*/_react.default.createElement(_Dropdown.default.Item, {
140
+ onClick: deleteFeatures
142
141
  }, /*#__PURE__*/_react.default.createElement(_reactFontawesome.FontAwesomeIcon, {
143
- icon: _freeSolidSvgIcons.faSliders
144
- }))), !!features?.features?.length && polygonControls, /*#__PURE__*/_react.default.createElement(_offcanvas.OffcanvasControls, {
142
+ icon: _freeSolidSvgIcons.faTrash,
143
+ className: "nav-icon"
144
+ }), "Delete polygons"))), !!features?.features?.length && polygonControls), /*#__PURE__*/_react.default.createElement(_offcanvas.OffcanvasControls, {
145
145
  show: showControls,
146
146
  handleClose: handleCloseControls,
147
147
  Controls: _ScatterplotControls.ScatterplotControls
@@ -7,8 +7,7 @@ exports.Toolbox = Toolbox;
7
7
  var _react = _interopRequireDefault(require("react"));
8
8
  var _freeSolidSvgIcons = require("@fortawesome/free-solid-svg-icons");
9
9
  var _reactFontawesome = require("@fortawesome/react-fontawesome");
10
- var _Button = _interopRequireDefault(require("react-bootstrap/Button"));
11
- var _ButtonGroup = _interopRequireDefault(require("react-bootstrap/ButtonGroup"));
10
+ var _reactBootstrap = require("react-bootstrap");
12
11
  var _string = require("../../utils/string");
13
12
  var _ObsmList = require("../obsm-list/ObsmList");
14
13
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
@@ -20,13 +19,44 @@ function Toolbox(_ref) {
20
19
  } = _ref;
21
20
  return /*#__PURE__*/_react.default.createElement("div", {
22
21
  className: "cherita-toolbox"
23
- }, /*#__PURE__*/_react.default.createElement(_ButtonGroup.default, null, /*#__PURE__*/_react.default.createElement(_ObsmList.ObsmKeysList, null), /*#__PURE__*/_react.default.createElement(_Button.default, {
24
- size: "sm"
22
+ }, /*#__PURE__*/_react.default.createElement(_reactBootstrap.ButtonGroup, null, /*#__PURE__*/_react.default.createElement(_ObsmList.ObsmKeysList, null), mode && /*#__PURE__*/_react.default.createElement(_reactBootstrap.OverlayTrigger, {
23
+ placement: "top",
24
+ overlay: /*#__PURE__*/_react.default.createElement(_reactBootstrap.Tooltip, {
25
+ id: "tooltip-dropped-mode"
26
+ }, "The color scale is currently set to ", mode)
27
+ }, /*#__PURE__*/_react.default.createElement(_reactBootstrap.Button, {
28
+ size: "sm",
29
+ variant: "primary",
30
+ style: {
31
+ cursor: "default"
32
+ },
33
+ "aria-disabled": "true"
25
34
  }, /*#__PURE__*/_react.default.createElement(_reactFontawesome.FontAwesomeIcon, {
26
- icon: _freeSolidSvgIcons.faDroplet
27
- }), " ", mode), (mode || !isNaN(obsLength)) && (mode !== null && !isNaN(slicedLength) && slicedLength !== obsLength ? /*#__PURE__*/_react.default.createElement(_Button.default, {
28
- size: "sm"
29
- }, (0, _string.formatNumerical)(slicedLength), " out of", " ", (0, _string.formatNumerical)(obsLength), " cells") : /*#__PURE__*/_react.default.createElement(_Button.default, {
30
- size: "sm"
31
- }, (0, _string.formatNumerical)(obsLength), " cells"))));
35
+ icon: _freeSolidSvgIcons.faDroplet,
36
+ className: "me-1"
37
+ }), " ", mode)), (mode || !isNaN(obsLength)) && (mode !== null && !isNaN(slicedLength) && slicedLength !== obsLength ? /*#__PURE__*/_react.default.createElement(_reactBootstrap.OverlayTrigger, {
38
+ placement: "top",
39
+ overlay: /*#__PURE__*/_react.default.createElement(_reactBootstrap.Tooltip, {
40
+ id: "tooltip-dropped-mode"
41
+ }, "You have selected ", (0, _string.formatNumerical)(slicedLength), " out of", " ", (0, _string.formatNumerical)(obsLength), " cells")
42
+ }, /*#__PURE__*/_react.default.createElement(_reactBootstrap.Button, {
43
+ size: "sm",
44
+ variant: "primary",
45
+ style: {
46
+ cursor: "default"
47
+ },
48
+ "aria-disabled": "true"
49
+ }, (0, _string.formatNumerical)(slicedLength), " of ", (0, _string.formatNumerical)(obsLength), " ", "cells")) : /*#__PURE__*/_react.default.createElement(_reactBootstrap.OverlayTrigger, {
50
+ placement: "top",
51
+ overlay: /*#__PURE__*/_react.default.createElement(_reactBootstrap.Tooltip, {
52
+ id: "tooltip-dropped-mode"
53
+ }, "You are viewing ", (0, _string.formatNumerical)(obsLength), " cells")
54
+ }, /*#__PURE__*/_react.default.createElement(_reactBootstrap.Button, {
55
+ size: "sm",
56
+ variant: "primary",
57
+ style: {
58
+ cursor: "default"
59
+ },
60
+ "aria-disabled": "true"
61
+ }, (0, _string.formatNumerical)(obsLength), " cells")))));
32
62
  }