@haniffalab/cherita-react 1.3.0-dev.2025-06-06.f1eddad0 → 1.3.1

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 (138) hide show
  1. package/README.md +1 -1
  2. package/dist/cjs/components/controls/Controls.js +38 -30
  3. package/dist/cjs/components/dotplot/Dotplot.js +67 -69
  4. package/dist/cjs/components/dotplot/DotplotControls.js +103 -83
  5. package/dist/cjs/components/full-page/FullPage.js +99 -105
  6. package/dist/cjs/components/full-page/PlotAlert.js +45 -0
  7. package/dist/cjs/components/full-page/PlotTypeSelector.js +89 -44
  8. package/dist/cjs/components/heatmap/Heatmap.js +65 -65
  9. package/dist/cjs/components/heatmap/HeatmapControls.js +6 -3
  10. package/dist/cjs/components/icons/DotPlotIcon.js +64 -0
  11. package/dist/cjs/components/icons/HeatmapIcon.js +45 -0
  12. package/dist/cjs/components/icons/MatrixPlotIcon.1.js +57 -0
  13. package/dist/cjs/components/icons/MatrixPlotIcon.js +59 -0
  14. package/dist/cjs/components/icons/ScatterplotIcon.1.js +164 -0
  15. package/dist/cjs/components/icons/ScatterplotIcon.js +144 -0
  16. package/dist/cjs/components/icons/ViolinPlotIcon.js +42 -0
  17. package/dist/cjs/components/matrixplot/Matrixplot.js +65 -66
  18. package/dist/cjs/components/matrixplot/MatrixplotControls.js +8 -5
  19. package/dist/cjs/components/obs-list/ObsItem.js +267 -205
  20. package/dist/cjs/components/obs-list/ObsList.js +161 -129
  21. package/dist/cjs/components/obs-list/ObsToolbar.js +2 -3
  22. package/dist/cjs/components/obsm-list/ObsmList.js +67 -28
  23. package/dist/cjs/components/offcanvas/index.js +62 -27
  24. package/dist/cjs/components/pseudospatial/Pseudospatial.js +132 -76
  25. package/dist/cjs/components/pseudospatial/PseudospatialToolbar.js +122 -74
  26. package/dist/cjs/components/scatterplot/Scatterplot.js +128 -100
  27. package/dist/cjs/components/scatterplot/ScatterplotControls.js +45 -31
  28. package/dist/cjs/components/scatterplot/SpatialControls.js +140 -113
  29. package/dist/cjs/components/scatterplot/Toolbox.js +41 -30
  30. package/dist/cjs/components/search-bar/SearchBar.js +176 -120
  31. package/dist/cjs/components/search-bar/SearchInfo.js +76 -50
  32. package/dist/cjs/components/search-bar/SearchResults.js +93 -71
  33. package/dist/cjs/components/toolbar/Toolbar.js +46 -37
  34. package/dist/cjs/components/var-list/VarItem.js +131 -103
  35. package/dist/cjs/components/var-list/VarList.js +85 -71
  36. package/dist/cjs/components/var-list/VarListToolbar.js +59 -54
  37. package/dist/cjs/components/var-list/VarSet.js +126 -108
  38. package/dist/cjs/components/violin/Violin.js +109 -97
  39. package/dist/cjs/components/violin/ViolinControls.js +8 -5
  40. package/dist/cjs/constants/colorscales.js +19 -19
  41. package/dist/cjs/constants/constants.js +51 -48
  42. package/dist/cjs/context/DatasetContext.js +26 -17
  43. package/dist/cjs/context/FilterContext.js +11 -9
  44. package/dist/cjs/context/SettingsContext.js +271 -88
  45. package/dist/cjs/context/ZarrDataContext.js +6 -5
  46. package/dist/cjs/helpers/color-helper.js +2 -2
  47. package/dist/cjs/helpers/zarr-helper.js +3 -3
  48. package/dist/cjs/utils/Filter.js +16 -11
  49. package/dist/cjs/utils/Histogram.js +35 -33
  50. package/dist/cjs/utils/ImageViewer.js +11 -8
  51. package/dist/cjs/utils/Legend.js +37 -30
  52. package/dist/cjs/utils/LoadingIndicators.js +15 -13
  53. package/dist/cjs/utils/Resolver.js +213 -0
  54. package/dist/cjs/utils/Skeleton.js +10 -10
  55. package/dist/cjs/utils/StyledTooltip.js +44 -0
  56. package/dist/cjs/utils/VirtualizedList.js +36 -29
  57. package/dist/cjs/utils/errors.js +15 -15
  58. package/dist/cjs/utils/requests.js +21 -9
  59. package/dist/cjs/utils/search.js +4 -4
  60. package/dist/cjs/utils/string.js +6 -6
  61. package/dist/cjs/utils/zarrData.js +20 -21
  62. package/dist/css/cherita.css +135 -65
  63. package/dist/css/cherita.css.map +1 -1
  64. package/dist/esm/components/controls/Controls.js +43 -35
  65. package/dist/esm/components/dotplot/Dotplot.js +77 -78
  66. package/dist/esm/components/dotplot/DotplotControls.js +106 -85
  67. package/dist/esm/components/full-page/FullPage.js +119 -124
  68. package/dist/esm/components/full-page/PlotAlert.js +39 -0
  69. package/dist/esm/components/full-page/PlotTypeSelector.js +90 -45
  70. package/dist/esm/components/heatmap/Heatmap.js +75 -74
  71. package/dist/esm/components/heatmap/HeatmapControls.js +8 -4
  72. package/dist/esm/components/icons/DotPlotIcon.js +58 -0
  73. package/dist/esm/components/icons/HeatmapIcon.js +39 -0
  74. package/dist/esm/components/icons/MatrixPlotIcon.1.js +51 -0
  75. package/dist/esm/components/icons/MatrixPlotIcon.js +53 -0
  76. package/dist/esm/components/icons/ScatterplotIcon.1.js +158 -0
  77. package/dist/esm/components/icons/ScatterplotIcon.js +138 -0
  78. package/dist/esm/components/icons/ViolinPlotIcon.js +36 -0
  79. package/dist/esm/components/matrixplot/Matrixplot.js +75 -75
  80. package/dist/esm/components/matrixplot/MatrixplotControls.js +10 -6
  81. package/dist/esm/components/obs-list/ObsItem.js +282 -217
  82. package/dist/esm/components/obs-list/ObsList.js +176 -143
  83. package/dist/esm/components/obs-list/ObsToolbar.js +3 -3
  84. package/dist/esm/components/obsm-list/ObsmList.js +71 -32
  85. package/dist/esm/components/offcanvas/index.js +68 -33
  86. package/dist/esm/components/pseudospatial/Pseudospatial.js +145 -88
  87. package/dist/esm/components/pseudospatial/PseudospatialToolbar.js +127 -78
  88. package/dist/esm/components/scatterplot/Scatterplot.js +149 -120
  89. package/dist/esm/components/scatterplot/ScatterplotControls.js +50 -35
  90. package/dist/esm/components/scatterplot/SpatialControls.js +153 -125
  91. package/dist/esm/components/scatterplot/Toolbox.js +44 -32
  92. package/dist/esm/components/search-bar/SearchBar.js +187 -130
  93. package/dist/esm/components/search-bar/SearchInfo.js +86 -59
  94. package/dist/esm/components/search-bar/SearchResults.js +100 -77
  95. package/dist/esm/components/toolbar/Toolbar.js +49 -39
  96. package/dist/esm/components/var-list/VarItem.js +142 -113
  97. package/dist/esm/components/var-list/VarList.js +99 -84
  98. package/dist/esm/components/var-list/VarListToolbar.js +64 -58
  99. package/dist/esm/components/var-list/VarSet.js +134 -115
  100. package/dist/esm/components/violin/Violin.js +121 -108
  101. package/dist/esm/components/violin/ViolinControls.js +10 -6
  102. package/dist/esm/constants/colorscales.js +19 -19
  103. package/dist/esm/constants/constants.js +50 -47
  104. package/dist/esm/context/DatasetContext.js +33 -23
  105. package/dist/esm/context/FilterContext.js +11 -8
  106. package/dist/esm/context/SettingsContext.js +273 -89
  107. package/dist/esm/context/ZarrDataContext.js +8 -6
  108. package/dist/esm/helpers/color-helper.js +5 -5
  109. package/dist/esm/helpers/map-helper.js +2 -2
  110. package/dist/esm/helpers/zarr-helper.js +6 -6
  111. package/dist/esm/index.js +22 -22
  112. package/dist/esm/utils/Filter.js +22 -17
  113. package/dist/esm/utils/Histogram.js +39 -37
  114. package/dist/esm/utils/ImageViewer.js +12 -8
  115. package/dist/esm/utils/Legend.js +44 -36
  116. package/dist/esm/utils/LoadingIndicators.js +16 -13
  117. package/dist/esm/utils/Resolver.js +201 -0
  118. package/dist/esm/utils/Skeleton.js +11 -10
  119. package/dist/esm/utils/StyledTooltip.js +38 -0
  120. package/dist/esm/utils/VirtualizedList.js +37 -29
  121. package/dist/esm/utils/errors.js +15 -15
  122. package/dist/esm/utils/requests.js +24 -12
  123. package/dist/esm/utils/search.js +7 -7
  124. package/dist/esm/utils/string.js +7 -7
  125. package/dist/esm/utils/zarrData.js +27 -28
  126. package/package.json +21 -10
  127. package/scss/cherita-bootstrap.scss +2 -2
  128. package/scss/cherita.scss +65 -16
  129. package/scss/components/accordions.scss +15 -2
  130. package/scss/components/layouts.scss +68 -50
  131. package/scss/components/lists.scss +16 -5
  132. package/scss/components/plotly.scss +38 -26
  133. package/scss/components/plots.scss +14 -1
  134. package/dist/assets/images/plots/dotplot.svg +0 -152
  135. package/dist/assets/images/plots/heatmap.svg +0 -193
  136. package/dist/assets/images/plots/matrixplot.svg +0 -275
  137. package/dist/assets/images/plots/scatterplot.svg +0 -198
  138. package/dist/assets/images/plots/violin.svg +0 -50
@@ -3,21 +3,24 @@ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t =
3
3
  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; }
4
4
  function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
5
5
  function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
6
- import React, { useEffect, useState } from "react";
7
- import { faCircleInfo } from "@fortawesome/free-solid-svg-icons";
8
- import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
9
- import _ from "lodash";
10
- import { Alert, Button, OverlayTrigger, Tooltip } from "react-bootstrap";
11
- import Plot from "react-plotly.js";
12
- import { PLOTLY_MODEBAR_BUTTONS, VIOLIN_MODES } from "../../constants/constants";
13
- import { useDataset } from "../../context/DatasetContext";
14
- import { useFilteredData } from "../../context/FilterContext";
15
- import { useSettings } from "../../context/SettingsContext";
16
- import { LoadingSpinner } from "../../utils/LoadingIndicators";
17
- import { useDebouncedFetch } from "../../utils/requests";
18
- import { ControlsPlotlyToolbar, ObsPlotlyToolbar, VarPlotlyToolbar } from "../toolbar/Toolbar";
6
+ import { useEffect, useMemo, useState } from 'react';
7
+ import { faCircleInfo } from '@fortawesome/free-solid-svg-icons';
8
+ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
9
+ import _ from 'lodash';
10
+ import { Badge, Button } from 'react-bootstrap';
11
+ import Plot from 'react-plotly.js';
12
+ import { PLOTLY_MODEBAR_BUTTONS, VIOLIN_MODES } from '../../constants/constants';
13
+ import { useDataset } from '../../context/DatasetContext';
14
+ import { useFilteredData } from '../../context/FilterContext';
15
+ import { useSettings } from '../../context/SettingsContext';
16
+ import { LoadingSpinner } from '../../utils/LoadingIndicators';
17
+ import { useDebouncedFetch } from '../../utils/requests';
18
+ import { useSelectedMultiVar, useSelectedObs, useSelectedVar } from '../../utils/Resolver';
19
+ import { StyledTooltip } from '../../utils/StyledTooltip';
20
+ import { PlotAlert } from '../full-page/PlotAlert';
21
+ import { ControlsPlotlyToolbar, ObsPlotlyToolbar, VarPlotlyToolbar } from '../toolbar/Toolbar';
22
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
19
23
  export function Violin(_ref) {
20
- var _settings$selectedVar, _settings$selectedVar2, _settings$selectedVar3, _settings$selectedVar4, _settings$selectedObs, _settings$selectedObs2, _settings$selectedObs3;
21
24
  let {
22
25
  mode = VIOLIN_MODES.MULTIKEY,
23
26
  showObsBtn = false,
@@ -25,9 +28,11 @@ export function Violin(_ref) {
25
28
  showCtrlsBtn = false,
26
29
  setShowObs,
27
30
  setShowVars,
28
- setShowControls
31
+ setShowControls,
32
+ plotType,
33
+ setPlotType
29
34
  } = _ref;
30
- const ENDPOINT = "violin";
35
+ const ENDPOINT = 'violin';
31
36
  const dataset = useDataset();
32
37
  const settings = useSettings();
33
38
  const {
@@ -37,91 +42,63 @@ export function Violin(_ref) {
37
42
  const [data, setData] = useState([]);
38
43
  const [layout, setLayout] = useState({});
39
44
  const [hasSelections, setHasSelections] = useState(false);
40
- const [params, setParams] = useState(_objectSpread({
45
+ const selectedMultiVar = useSelectedMultiVar();
46
+ const selectedVar = useSelectedVar();
47
+ const selectedObs = useSelectedObs();
48
+ const params = useMemo(() => _objectSpread({
41
49
  url: dataset.url,
42
50
  mode: mode,
43
51
  scale: settings.controls.scale.violinplot,
44
52
  varNamesCol: dataset.varNamesCol
45
53
  }, {
46
54
  [VIOLIN_MODES.MULTIKEY]: {
47
- varKeys: settings.selectedMultiVar.map(i => i.isSet ? {
55
+ varKeys: selectedMultiVar.map(i => i.isSet ? {
48
56
  name: i.name,
49
57
  indices: i.vars.map(v => v.index)
50
58
  } : i.index),
51
59
  obsKeys: [] // @TODO: implement
52
60
  },
53
61
  [VIOLIN_MODES.GROUPBY]: {
54
- varKey: (_settings$selectedVar = settings.selectedVar) !== null && _settings$selectedVar !== void 0 && _settings$selectedVar.isSet ? {
55
- name: (_settings$selectedVar2 = settings.selectedVar) === null || _settings$selectedVar2 === void 0 ? void 0 : _settings$selectedVar2.name,
56
- indices: (_settings$selectedVar3 = settings.selectedVar) === null || _settings$selectedVar3 === void 0 ? void 0 : _settings$selectedVar3.vars.map(v => v.index)
57
- } : (_settings$selectedVar4 = settings.selectedVar) === null || _settings$selectedVar4 === void 0 ? void 0 : _settings$selectedVar4.index,
58
- obsCol: settings.selectedObs,
59
- obsValues: !((_settings$selectedObs = settings.selectedObs) !== null && _settings$selectedObs !== void 0 && _settings$selectedObs.omit.length) ? null : _.difference(_.values((_settings$selectedObs2 = settings.selectedObs) === null || _settings$selectedObs2 === void 0 ? void 0 : _settings$selectedObs2.codes), (_settings$selectedObs3 = settings.selectedObs) === null || _settings$selectedObs3 === void 0 ? void 0 : _settings$selectedObs3.omit).map(c => {
60
- var _settings$selectedObs4;
61
- return (_settings$selectedObs4 = settings.selectedObs) === null || _settings$selectedObs4 === void 0 ? void 0 : _settings$selectedObs4.codesMap[c];
62
- }),
62
+ varKey: selectedVar !== null && selectedVar !== void 0 && selectedVar.isSet ? {
63
+ name: selectedVar === null || selectedVar === void 0 ? void 0 : selectedVar.name,
64
+ indices: selectedVar === null || selectedVar === void 0 ? void 0 : selectedVar.vars.map(v => v.index)
65
+ } : selectedVar === null || selectedVar === void 0 ? void 0 : selectedVar.index,
66
+ obsCol: selectedObs,
67
+ obsValues: !(selectedObs !== null && selectedObs !== void 0 && selectedObs.omit.length) ? null : _.difference(selectedObs === null || selectedObs === void 0 ? void 0 : selectedObs.values, selectedObs === null || selectedObs === void 0 ? void 0 : selectedObs.omit),
63
68
  obsIndices: isSliced ? [...(obsIndices || [])] : null
64
69
  }
65
- }[mode]));
70
+ }[mode]), [dataset.url, dataset.varNamesCol, isSliced, mode, obsIndices, selectedMultiVar, selectedObs, selectedVar === null || selectedVar === void 0 ? void 0 : selectedVar.index, selectedVar === null || selectedVar === void 0 ? void 0 : selectedVar.isSet, selectedVar === null || selectedVar === void 0 ? void 0 : selectedVar.name, selectedVar === null || selectedVar === void 0 ? void 0 : selectedVar.vars, settings.controls.scale.violinplot]);
66
71
  // @TODO: set default scale
67
72
 
68
73
  useEffect(() => {
69
74
  if (mode === VIOLIN_MODES.MULTIKEY) {
70
- if (settings.selectedMultiVar.length) {
75
+ if (selectedMultiVar.length) {
71
76
  setHasSelections(true);
72
77
  } else {
73
78
  setHasSelections(false);
74
79
  }
75
- setParams(p => {
76
- return _objectSpread(_objectSpread({}, p), {}, {
77
- url: dataset.url,
78
- mode: mode,
79
- varKeys: settings.selectedMultiVar.map(i => i.isSet ? {
80
- name: i.name,
81
- indices: i.vars.map(v => v.index)
82
- } : i.index),
83
- scale: settings.controls.scale.violinplot,
84
- varNamesCol: dataset.varNamesCol
85
- });
86
- });
87
80
  } else if (mode === VIOLIN_MODES.GROUPBY) {
88
- if (settings.selectedObs && settings.selectedVar) {
81
+ if (selectedObs && selectedVar) {
89
82
  setHasSelections(true);
90
83
  } else {
91
84
  setHasSelections(false);
92
85
  }
93
- setParams(p => {
94
- var _settings$selectedVar5, _settings$selectedVar6, _settings$selectedVar7, _settings$selectedVar8, _settings$selectedObs5, _settings$selectedObs6, _settings$selectedObs7;
95
- return _objectSpread(_objectSpread({}, p), {}, {
96
- url: dataset.url,
97
- mode: mode,
98
- varKey: (_settings$selectedVar5 = settings.selectedVar) !== null && _settings$selectedVar5 !== void 0 && _settings$selectedVar5.isSet ? {
99
- name: (_settings$selectedVar6 = settings.selectedVar) === null || _settings$selectedVar6 === void 0 ? void 0 : _settings$selectedVar6.name,
100
- indices: (_settings$selectedVar7 = settings.selectedVar) === null || _settings$selectedVar7 === void 0 ? void 0 : _settings$selectedVar7.vars.map(v => v.index)
101
- } : (_settings$selectedVar8 = settings.selectedVar) === null || _settings$selectedVar8 === void 0 ? void 0 : _settings$selectedVar8.index,
102
- obsCol: settings.selectedObs,
103
- obsValues: !((_settings$selectedObs5 = settings.selectedObs) !== null && _settings$selectedObs5 !== void 0 && _settings$selectedObs5.omit.length) ? null : _.difference(_.values((_settings$selectedObs6 = settings.selectedObs) === null || _settings$selectedObs6 === void 0 ? void 0 : _settings$selectedObs6.codes), (_settings$selectedObs7 = settings.selectedObs) === null || _settings$selectedObs7 === void 0 ? void 0 : _settings$selectedObs7.omit).map(c => {
104
- var _settings$selectedObs8;
105
- return (_settings$selectedObs8 = settings.selectedObs) === null || _settings$selectedObs8 === void 0 ? void 0 : _settings$selectedObs8.codesMap[c];
106
- }),
107
- obsIndices: isSliced ? [...(obsIndices || [])] : null,
108
- scale: settings.controls.scale.violinplot,
109
- varNamesCol: dataset.varNamesCol
110
- });
111
- });
112
86
  }
113
- }, [settings.controls.scale.violinplot, settings.selectedMultiVar, settings.selectedObs, settings.selectedVar, dataset.url, dataset.varNamesCol, obsIndices, isSliced, mode]);
87
+ }, [settings.controls.scale.violinplot, selectedMultiVar, selectedObs, selectedVar, dataset.url, dataset.varNamesCol, obsIndices, isSliced, mode]);
114
88
  const {
115
89
  fetchedData,
116
90
  isPending,
117
91
  serverError
118
92
  } = useDebouncedFetch(ENDPOINT, params, 500, {
119
- enabled: mode === VIOLIN_MODES.MULTIKEY && (!!params.varKeys.length || !!params.obsKeys.length) || mode === VIOLIN_MODES.GROUPBY && !!params.varKey && !!params.obsCol
93
+ isEnabled: mode === VIOLIN_MODES.MULTIKEY && (params => !!params.varKeys.length || !!params.obsKeys.length) || mode === VIOLIN_MODES.GROUPBY && (params => !!params.varKey && !!params.obsCol)
120
94
  });
121
95
  useEffect(() => {
122
- if (hasSelections && !isPending && !serverError) {
96
+ if (hasSelections && !!fetchedData && !isPending && !serverError) {
123
97
  setData(fetchedData.data);
124
98
  setLayout(fetchedData.layout);
99
+ } else {
100
+ setData([]);
101
+ setLayout({});
125
102
  }
126
103
  }, [fetchedData, hasSelections, isPending, serverError]);
127
104
  const customModeBarButtons = _.compact([showObsBtn && ObsPlotlyToolbar({
@@ -134,51 +111,87 @@ export function Violin(_ref) {
134
111
  const modeBarButtons = customModeBarButtons.length ? [customModeBarButtons, PLOTLY_MODEBAR_BUTTONS] : [PLOTLY_MODEBAR_BUTTONS];
135
112
  if (!serverError) {
136
113
  if (hasSelections) {
137
- return /*#__PURE__*/React.createElement("div", {
138
- className: "cherita-plot cherita-violin position-relative"
139
- }, isPending && /*#__PURE__*/React.createElement(LoadingSpinner, null), /*#__PURE__*/React.createElement(Plot, {
140
- data: data,
141
- layout: layout,
142
- useResizeHandler: true,
143
- style: {
144
- width: "100%",
145
- height: "100%"
146
- },
147
- config: {
148
- displaylogo: false,
149
- modeBarButtons: modeBarButtons
150
- }
151
- }), (fetchedData === null || fetchedData === void 0 ? void 0 : fetchedData.resampled) && /*#__PURE__*/React.createElement(Alert, {
152
- variant: "warning"
153
- }, /*#__PURE__*/React.createElement("b", null, "Warning:"), " For performance reasons this plot was generated with resampled data. It will not be exactly the same as one produced with the entire dataset. \xA0", /*#__PURE__*/React.createElement(OverlayTrigger, {
154
- placement: "top",
155
- overlay: /*#__PURE__*/React.createElement(Tooltip, null, "Resampled to 100K values following a Monte Carlo style approach to help ensure resampled data is a good representation of the original dataset's distribution.")
156
- }, /*#__PURE__*/React.createElement(FontAwesomeIcon, {
157
- icon: faCircleInfo
158
- }))));
114
+ return /*#__PURE__*/_jsxs("div", {
115
+ className: "cherita-plot cherita-violin",
116
+ children: [isPending && /*#__PURE__*/_jsx(LoadingSpinner, {}), /*#__PURE__*/_jsxs("div", {
117
+ className: "d-flex flex-column h-100",
118
+ children: [/*#__PURE__*/_jsx("div", {
119
+ className: "flex-grow-1 position-relative",
120
+ style: {
121
+ minHeight: '0'
122
+ },
123
+ children: /*#__PURE__*/_jsx(Plot, {
124
+ data: data,
125
+ layout: layout,
126
+ useResizeHandler: true,
127
+ style: {
128
+ width: '100%',
129
+ height: '100%'
130
+ },
131
+ config: {
132
+ displaylogo: false,
133
+ modeBarButtons: modeBarButtons
134
+ }
135
+ })
136
+ }), (fetchedData === null || fetchedData === void 0 ? void 0 : fetchedData.resampled) && /*#__PURE__*/_jsx("div", {
137
+ className: "resampled-tooltip-container",
138
+ children: /*#__PURE__*/_jsx(StyledTooltip, {
139
+ title: /*#__PURE__*/_jsxs(_Fragment, {
140
+ children: [/*#__PURE__*/_jsx("strong", {
141
+ children: "Note:"
142
+ }), " This plot uses resampled data to improve performance, so values may differ slightly from the full dataset. The data were resampled to exactly 100,000 values using a Monte Carlo\u2013style approach to provide a representative view of the full distribution while reducing processing time."]
143
+ }),
144
+ placement: "bottom",
145
+ children: /*#__PURE__*/_jsxs(Badge, {
146
+ bg: "info",
147
+ children: [/*#__PURE__*/_jsx(FontAwesomeIcon, {
148
+ className: "fs-6",
149
+ icon: faCircleInfo
150
+ }), /*#__PURE__*/_jsx("span", {
151
+ className: "d-none d-lg-inline ms-2 fs-6 text-uppercase",
152
+ children: "Resampled"
153
+ })]
154
+ })
155
+ })
156
+ })]
157
+ })]
158
+ });
159
159
  }
160
- return /*#__PURE__*/React.createElement("div", {
161
- className: "cherita-violin"
162
- }, mode === VIOLIN_MODES.MULTIKEY && /*#__PURE__*/React.createElement(Alert, {
163
- variant: "light"
164
- }, "Select", " ", showVarsBtn ? /*#__PURE__*/React.createElement(Button, {
165
- variant: "link",
166
- className: "border-0 p-0 align-baseline",
167
- onClick: setShowVars
168
- }, "features") : "features"), mode === VIOLIN_MODES.GROUPBY && /*#__PURE__*/React.createElement(Alert, {
169
- variant: "light"
170
- }, "Select", " ", showObsBtn ? /*#__PURE__*/React.createElement(Button, {
171
- variant: "link",
172
- className: "border-0 p-0 align-baseline",
173
- onClick: setShowObs
174
- }, "categories") : "categories", " ", "and a", " ", showVarsBtn ? /*#__PURE__*/React.createElement(Button, {
175
- variant: "link",
176
- className: "border-0 p-0 align-baseline",
177
- onClick: setShowVars
178
- }, "feature") : "feature"));
160
+ return /*#__PURE__*/_jsxs(PlotAlert, {
161
+ variant: "info",
162
+ heading: "Set up your violin plot",
163
+ plotType: plotType,
164
+ setPlotType: setPlotType,
165
+ children: [mode === VIOLIN_MODES.MULTIKEY && /*#__PURE__*/_jsxs("p", {
166
+ className: "p-0 m-0",
167
+ children: ["Select one or more", ' ', showVarsBtn ? /*#__PURE__*/_jsx(Button, {
168
+ variant: "link",
169
+ className: "border-0 p-0 align-baseline",
170
+ onClick: setShowVars,
171
+ children: "features"
172
+ }) : 'features', ' ', "to display their expression distributions across all observations."]
173
+ }), mode === VIOLIN_MODES.GROUPBY && /*#__PURE__*/_jsxs("p", {
174
+ className: "p-0 m-0",
175
+ children: ["Select a", ' ', showObsBtn ? /*#__PURE__*/_jsx(Button, {
176
+ variant: "link",
177
+ className: "border-0 p-0 align-baseline",
178
+ onClick: setShowObs,
179
+ children: "category"
180
+ }) : 'category', ' ', "to group observations, and choose a", ' ', showVarsBtn ? /*#__PURE__*/_jsx(Button, {
181
+ variant: "link",
182
+ className: "border-0 p-0 align-baseline",
183
+ onClick: setShowVars,
184
+ children: "feature"
185
+ }) : 'feature', ' ', "to view its distribution within each group."]
186
+ })]
187
+ });
179
188
  } else {
180
- return /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(Alert, {
181
- variant: "danger"
182
- }, serverError.message));
189
+ return /*#__PURE__*/_jsx(PlotAlert, {
190
+ variant: "danger",
191
+ heading: "Error displaying the violin plot",
192
+ plotType: plotType,
193
+ setPlotType: setPlotType,
194
+ children: serverError.message || 'An unexpected error occurred while generating the plot.'
195
+ });
183
196
  }
184
197
  }
@@ -1,8 +1,12 @@
1
- import React from "react";
2
- import { Form } from "react-bootstrap";
3
- import { ScaleSelect } from "../controls/Controls";
1
+ import { Form } from 'react-bootstrap';
2
+ import { ScaleSelect } from '../controls/Controls';
3
+ import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
4
4
  export function ViolinControls() {
5
- return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Form, null, /*#__PURE__*/React.createElement(ScaleSelect, {
6
- plot: "violinplot"
7
- })));
5
+ return /*#__PURE__*/_jsx(_Fragment, {
6
+ children: /*#__PURE__*/_jsx(Form, {
7
+ children: /*#__PURE__*/_jsx(ScaleSelect, {
8
+ plot: "violinplot"
9
+ })
10
+ })
11
+ });
8
12
  }
@@ -1,22 +1,22 @@
1
1
  // From plotly https://github.com/plotly/plotly.js/blob/5bc25b490702e5ed61265207833dbd58e8ab27f1/src/components/colorscale/scales.js
2
2
  export const COLORSCALES = {
3
- Greys: ["#000000", "#ffffff"],
4
- YlGnBu: ["#081d58", "#253494", "#225ea8", "#1d91c0", "#41b6c4", "#7fcdbb", "#c7e9b4", "#edf8d9", "#ffffd9"],
5
- Greens: ["#00441b", "#006d2c", "#238b45", "#41ab5d", "#74c476", "#a1d9a5", "#c7e9c0", "#e5f5e0", "#f7fcf5"],
6
- YlOrRd: ["#800026", "#bd0026", "#e31a1c", "#fc4e2a", "#fd8d3c", "#feb24c", "#fed976", "#ffed9f", "#ffffcc"],
7
- Bluered: ["#0000ff", "#ff0000"],
8
- RdBu: ["#050aac", "#6a89f7", "#bebebe", "#dcaa84", "#e6915a", "#b20a1c"],
9
- Reds: ["#dcdcdc", "#f5c39d", "#f5a069", "#b20a1c"],
10
- Blues: ["#050aac", "#283cba", "#4664f5", "#5a78f5", "#6a89f7", "#dcdcdc"],
11
- Picnic: ["#0000ff", "#3399ff", "#66ccff", "#99ccff", "#ccccff", "#ffffff", "#ffccff", "#ff99ff", "#ff66cc", "#ff6666", "#ff0000"],
12
- Rainbow: ["#96005a", "#0000c8", "#0019ff", "#0098ff", "#2cff96", "#97ff00", "#ffe600", "#ff6f00", "#ff0000"],
13
- Portland: ["#0c3383", "#0a88ba", "#f2d338", "#f28f38", "#d91e1e"],
14
- Jet: ["#000083", "#003caa", "#05ffff", "#ffff00", "#fa0000", "#800000"],
15
- Hot: ["#000000", "#e60000", "#ffd200", "#ffffff"],
16
- Blackbody: ["#000000", "#e60000", "#e6d200", "#ffffff", "#a0c8ff"],
17
- Earth: ["#000082", "#00b4b4", "#28d228", "#e6e632", "#784614", "#ffffff"],
18
- Electric: ["#000000", "#1e0064", "#780064", "#a05a00", "#e6c800", "#fffadc"],
19
- Viridis: ["#440154", "#48186a", "#472d7b", "#424086", "#3b528b", "#33638d", "#2c728e", "#26828e", "#21918c", "#1fa088", "#28ae80", "#3fbc73", "#5ec962", "#84d44b", "#addc30", "#d8e219", "#fde725"],
20
- Cividis: ["#00204c", "#002a66", "#00346e", "#273f6c", "#3c4a6c", "#4c556b", "#5b5f6d", "#686a70", "#757575", "#838178", "#929c78", "#a19676", "#b0a572", "#c0af6d", "#d1ba65", "#e1c75c", "#f3db4f", "#ffe945"],
21
- Accent: ["#7fc97f", "#beaed4", "#fdc086", "#ffff99", "#386cb0", "#f0027f", "#bf5b17", "#666666"]
3
+ Greys: ['#000000', '#ffffff'],
4
+ YlGnBu: ['#081d58', '#253494', '#225ea8', '#1d91c0', '#41b6c4', '#7fcdbb', '#c7e9b4', '#edf8d9', '#ffffd9'],
5
+ Greens: ['#00441b', '#006d2c', '#238b45', '#41ab5d', '#74c476', '#a1d9a5', '#c7e9c0', '#e5f5e0', '#f7fcf5'],
6
+ YlOrRd: ['#800026', '#bd0026', '#e31a1c', '#fc4e2a', '#fd8d3c', '#feb24c', '#fed976', '#ffed9f', '#ffffcc'],
7
+ Bluered: ['#0000ff', '#ff0000'],
8
+ RdBu: ['#050aac', '#6a89f7', '#bebebe', '#dcaa84', '#e6915a', '#b20a1c'],
9
+ Reds: ['#dcdcdc', '#f5c39d', '#f5a069', '#b20a1c'],
10
+ Blues: ['#050aac', '#283cba', '#4664f5', '#5a78f5', '#6a89f7', '#dcdcdc'],
11
+ Picnic: ['#0000ff', '#3399ff', '#66ccff', '#99ccff', '#ccccff', '#ffffff', '#ffccff', '#ff99ff', '#ff66cc', '#ff6666', '#ff0000'],
12
+ Rainbow: ['#96005a', '#0000c8', '#0019ff', '#0098ff', '#2cff96', '#97ff00', '#ffe600', '#ff6f00', '#ff0000'],
13
+ Portland: ['#0c3383', '#0a88ba', '#f2d338', '#f28f38', '#d91e1e'],
14
+ Jet: ['#000083', '#003caa', '#05ffff', '#ffff00', '#fa0000', '#800000'],
15
+ Hot: ['#000000', '#e60000', '#ffd200', '#ffffff'],
16
+ Blackbody: ['#000000', '#e60000', '#e6d200', '#ffffff', '#a0c8ff'],
17
+ Earth: ['#000082', '#00b4b4', '#28d228', '#e6e632', '#784614', '#ffffff'],
18
+ Electric: ['#000000', '#1e0064', '#780064', '#a05a00', '#e6c800', '#fffadc'],
19
+ Viridis: ['#440154', '#48186a', '#472d7b', '#424086', '#3b528b', '#33638d', '#2c728e', '#26828e', '#21918c', '#1fa088', '#28ae80', '#3fbc73', '#5ec962', '#84d44b', '#addc30', '#d8e219', '#fde725'],
20
+ Cividis: ['#00204c', '#002a66', '#00346e', '#273f6c', '#3c4a6c', '#4c556b', '#5b5f6d', '#686a70', '#757575', '#838178', '#929c78', '#a19676', '#b0a572', '#c0af6d', '#d1ba65', '#e1c75c', '#f3db4f', '#ffe945'],
21
+ Accent: ['#7fc97f', '#beaed4', '#fdc086', '#ffff99', '#386cb0', '#f0027f', '#bf5b17', '#666666']
22
22
  };
@@ -1,100 +1,103 @@
1
- export const LOCAL_STORAGE_KEY = "CHERITA";
1
+ export const LOCAL_STORAGE_KEY = 'CHERITA';
2
2
  export const PLOT_TYPES = {
3
- SCATTERPLOT: "scatterplot",
4
- DOTPLOT: "dotplot",
5
- HEATMAP: "heatmap",
6
- MATRIXPLOT: "matrixplot",
7
- VIOLINPLOT: "violinplot"
3
+ SCATTERPLOT: 'scatterplot',
4
+ DOTPLOT: 'dotplot',
5
+ HEATMAP: 'heatmap',
6
+ MATRIXPLOT: 'matrixplot',
7
+ VIOLINPLOT: 'violinplot'
8
8
  };
9
9
  export const COLOR_ENCODINGS = {
10
- VAR: "var",
11
- OBS: "obs"
10
+ VAR: 'var',
11
+ OBS: 'obs'
12
12
  };
13
13
  export const OBS_TYPES = {
14
- CATEGORICAL: "categorical",
15
- DISCRETE: "discrete",
16
- CONTINUOUS: "continuous",
17
- BOOLEAN: "boolean"
14
+ CATEGORICAL: 'categorical',
15
+ DISCRETE: 'discrete',
16
+ CONTINUOUS: 'continuous',
17
+ BOOLEAN: 'boolean'
18
18
  };
19
19
  export const VAR_SORT = {
20
20
  NONE: null,
21
- NAME: "name",
22
- MATRIX: "matrix"
21
+ NAME: 'name',
22
+ MATRIX: 'matrix'
23
23
  };
24
24
  export const VAR_SORT_ORDER = {
25
- ASC: "asc",
26
- DESC: "desc"
25
+ ASC: 'asc',
26
+ DESC: 'desc'
27
27
  };
28
28
  export const SELECTED_POLYGON_FILLCOLOR = [107, 170, 209, 255 / 2];
29
29
  export const UNSELECTED_POLYGON_FILLCOLOR = [167, 191, 211, 255 / 3];
30
30
  export const SELECTION_MODES = {
31
- SINGLE: "single",
32
- MULTIPLE: "multiple"
31
+ SINGLE: 'single',
32
+ MULTIPLE: 'multiple'
33
33
  };
34
34
  export const VIOLIN_MODES = {
35
- MULTIKEY: "multikey",
36
- GROUPBY: "groupby"
35
+ MULTIKEY: 'multikey',
36
+ GROUPBY: 'groupby'
37
37
  };
38
38
  export const MATRIXPLOT_SCALES = {
39
39
  NONE: {
40
40
  value: null,
41
- name: "None"
41
+ name: 'None'
42
42
  },
43
43
  GROUP: {
44
- value: "group",
45
- name: "Group"
44
+ value: 'group',
45
+ name: 'Group'
46
46
  },
47
47
  VAR: {
48
- value: "var",
49
- name: "Var"
48
+ value: 'var',
49
+ name: 'Var'
50
50
  }
51
51
  };
52
52
  export const DOTPLOT_SCALES = {
53
53
  NONE: {
54
54
  value: null,
55
- name: "None"
55
+ name: 'None'
56
56
  },
57
57
  GROUP: {
58
- value: "group",
59
- name: "Group"
58
+ value: 'group',
59
+ name: 'Group'
60
60
  },
61
61
  VAR: {
62
- value: "var",
63
- name: "Var"
62
+ value: 'var',
63
+ name: 'Var'
64
64
  }
65
65
  };
66
66
  export const VIOLINPLOT_SCALES = {
67
67
  WIDTH: {
68
- value: "width",
69
- name: "Width"
68
+ value: 'width',
69
+ name: 'Width'
70
70
  },
71
71
  COUNT: {
72
- value: "count",
73
- name: "Count"
72
+ value: 'count',
73
+ name: 'Count'
74
74
  }
75
75
  };
76
76
  export const PSEUDOSPATIAL_PLOT_TYPES = {
77
- GENE: "gene",
78
- CATEGORICAL: "categorical",
79
- CONTINUOUS: "continuous",
80
- MASKS: "masks"
77
+ GENE: 'gene',
78
+ CATEGORICAL: 'categorical',
79
+ CONTINUOUS: 'continuous',
80
+ MASKS: 'masks'
81
81
  };
82
82
  export const PSEUDOSPATIAL_CATEGORICAL_MODES = {
83
83
  ACROSS: {
84
- value: "across",
85
- name: "% across sections"
84
+ value: 'across',
85
+ name: '% across sections'
86
86
  },
87
87
  WITHIN: {
88
- value: "within",
89
- name: "% within section"
88
+ value: 'within',
89
+ name: '% within section'
90
90
  }
91
91
  };
92
92
 
93
93
  // `default` cols to be shown out of accordion, at top of obslist
94
94
  // default values from cellxgene schema
95
- export const DEFAULT_OBS_GROUP = ["assay", "cell_type", "development_stage", "disease", "donor_id", "organism", "self_reported_ethnicity", "sex", "suspension_type", "tissue", "tissue_type"];
96
- export const PLOTLY_MODEBAR_BUTTONS = ["toImage", "zoom2d", "pan2d", "zoomIn2d", "zoomOut2d", "autoScale2d", "resetScale2d"];
95
+ export const DEFAULT_OBS_GROUP = ['assay', 'cell_type', 'development_stage', 'disease', 'donor_id', 'organism', 'self_reported_ethnicity', 'sex', 'suspension_type', 'tissue', 'tissue_type'];
96
+ export const PLOTLY_MODEBAR_BUTTONS = ['toImage', 'zoom2d', 'pan2d', 'zoomIn2d', 'zoomOut2d', 'autoScale2d', 'resetScale2d'];
97
97
  export const BREAKPOINTS = {
98
- LG: "(max-width: 991.98px)",
99
- XL: "(max-width: 1199.98px)"
100
- };
98
+ LG: '(max-width: 991.98px)',
99
+ XL: '(max-width: 1199.98px)'
100
+ };
101
+
102
+ // In order of priority
103
+ export const DEFAULT_OBSM_KEYS = ['x_umap', 'x_tsne', 'x_scvi', 'x_pca'];
@@ -6,14 +6,15 @@ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol"
6
6
  function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
7
7
  function _objectWithoutProperties(e, t) { if (null == e) return {}; var o, r, i = _objectWithoutPropertiesLoose(e, t); if (Object.getOwnPropertySymbols) { var n = Object.getOwnPropertySymbols(e); for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]); } return i; }
8
8
  function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
9
- import React, { createContext, useContext } from "react";
10
- import { createSyncStoragePersister } from "@tanstack/query-sync-storage-persister";
11
- import { QueryClient, QueryCache } from "@tanstack/react-query";
12
- import { PersistQueryClientProvider } from "@tanstack/react-query-persist-client";
13
- import _ from "lodash";
14
- import { FilterProvider } from "./FilterContext";
15
- import { SettingsProvider } from "./SettingsContext";
16
- import { ZarrDataProvider } from "./ZarrDataContext";
9
+ import { createContext, useContext } from 'react';
10
+ import { createSyncStoragePersister } from '@tanstack/query-sync-storage-persister';
11
+ import { QueryClient, QueryCache } from '@tanstack/react-query';
12
+ import { PersistQueryClientProvider } from '@tanstack/react-query-persist-client';
13
+ import _ from 'lodash';
14
+ import { FilterProvider } from './FilterContext';
15
+ import { SettingsProvider } from './SettingsContext';
16
+ import { ZarrDataProvider } from './ZarrDataContext';
17
+ import { jsx as _jsx } from "react/jsx-runtime";
17
18
  export const DatasetContext = /*#__PURE__*/createContext(null);
18
19
  const queryClient = new QueryClient({
19
20
  defaultOptions: {
@@ -33,7 +34,7 @@ const queryClient = new QueryClient({
33
34
  })
34
35
  });
35
36
  // Type of queries to store responses
36
- const persistKeys = ["obs/cols", "var/names", "obsm/keys", "obs/bins", "obs/distribution"];
37
+ const persistKeys = ['obs/cols', 'var/names', 'obsm/keys', 'obs/bins', 'obs/distribution'];
37
38
  const persistOptions = {
38
39
  persister: createSyncStoragePersister({
39
40
  storage: window.localStorage
@@ -44,13 +45,14 @@ const persistOptions = {
44
45
  queryKey,
45
46
  state
46
47
  } = _ref;
47
- if (state.status === "success") {
48
+ if (state.status === 'success') {
48
49
  return persistKeys.includes(queryKey === null || queryKey === void 0 ? void 0 : queryKey[0]);
49
50
  }
50
51
  return false;
51
52
  }
52
- }
53
- // @TODO: add maxAge and buster (app and api version numbers as busters)
53
+ },
54
+ buster: "1.3.1" || '0.0.0'
55
+ // @TODO: add maxAge and api version numbers as buster
54
56
  };
55
57
  const initialDataset = {
56
58
  url: null,
@@ -60,7 +62,8 @@ const initialDataset = {
60
62
  imageUrl: null,
61
63
  defaultSettings: {},
62
64
  canOverrideSettings: true,
63
- useUnsColors: false
65
+ useUnsColors: false,
66
+ isPseudospatial: false
64
67
  };
65
68
  export function DatasetProvider(_ref2) {
66
69
  let {
@@ -71,16 +74,23 @@ export function DatasetProvider(_ref2) {
71
74
  const dataset = _.assign(initialDataset, _objectSpread({
72
75
  url: dataset_url
73
76
  }, dataset_params));
74
- return /*#__PURE__*/React.createElement(DatasetContext.Provider, {
75
- value: dataset
76
- }, /*#__PURE__*/React.createElement(SettingsProvider, {
77
- dataset_url: dataset.url,
78
- defaultSettings: dataset.defaultSettings,
79
- canOverrideSettings: dataset.canOverrideSettings
80
- }, /*#__PURE__*/React.createElement(PersistQueryClientProvider, {
81
- client: queryClient,
82
- persistOptions: persistOptions
83
- }, /*#__PURE__*/React.createElement(FilterProvider, null, /*#__PURE__*/React.createElement(ZarrDataProvider, null, children)))));
77
+ return /*#__PURE__*/_jsx(DatasetContext.Provider, {
78
+ value: dataset,
79
+ children: /*#__PURE__*/_jsx(PersistQueryClientProvider, {
80
+ client: queryClient,
81
+ persistOptions: persistOptions,
82
+ children: /*#__PURE__*/_jsx(SettingsProvider, {
83
+ dataset_url: dataset.url,
84
+ defaultSettings: dataset.defaultSettings,
85
+ canOverrideSettings: dataset.canOverrideSettings,
86
+ children: /*#__PURE__*/_jsx(FilterProvider, {
87
+ children: /*#__PURE__*/_jsx(ZarrDataProvider, {
88
+ children: children
89
+ })
90
+ })
91
+ })
92
+ })
93
+ });
84
94
  }
85
95
  export function useDataset() {
86
96
  return useContext(DatasetContext);