@haniffalab/cherita-react 1.4.1-dev.2025-10-20.528e0f75 → 1.4.1-dev.2025-10-22.61540191

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 (50) hide show
  1. package/dist/cjs/components/dotplot/Dotplot.js +23 -15
  2. package/dist/cjs/components/full-page/FullPage.js +32 -30
  3. package/dist/cjs/components/full-page/PlotAlert.js +36 -0
  4. package/dist/cjs/components/full-page/PlotTypeSelector.js +77 -39
  5. package/dist/cjs/components/heatmap/Heatmap.js +23 -15
  6. package/dist/cjs/components/icons/DotPlotIcon.js +58 -0
  7. package/dist/cjs/components/icons/HeatmapIcon.js +39 -0
  8. package/dist/cjs/components/icons/MatrixPlotIcon.1.js +51 -0
  9. package/dist/cjs/components/icons/MatrixPlotIcon.js +53 -0
  10. package/dist/cjs/components/icons/ScatterplotIcon.1.js +158 -0
  11. package/dist/cjs/components/icons/ScatterplotIcon.js +138 -0
  12. package/dist/cjs/components/icons/ViolinPlotIcon.js +34 -0
  13. package/dist/cjs/components/matrixplot/Matrixplot.js +25 -17
  14. package/dist/cjs/components/pseudospatial/Pseudospatial.js +64 -25
  15. package/dist/cjs/components/pseudospatial/PseudospatialToolbar.js +63 -15
  16. package/dist/cjs/components/violin/Violin.js +41 -30
  17. package/dist/cjs/context/DatasetContext.js +1 -1
  18. package/dist/cjs/context/SettingsContext.js +27 -3
  19. package/dist/cjs/utils/StyledTooltip.js +39 -0
  20. package/dist/css/cherita.css +37 -22
  21. package/dist/css/cherita.css.map +1 -1
  22. package/dist/esm/components/dotplot/Dotplot.js +22 -13
  23. package/dist/esm/components/full-page/FullPage.js +6 -3
  24. package/dist/esm/components/full-page/PlotAlert.js +30 -0
  25. package/dist/esm/components/full-page/PlotTypeSelector.js +76 -38
  26. package/dist/esm/components/heatmap/Heatmap.js +22 -13
  27. package/dist/esm/components/icons/DotPlotIcon.js +52 -0
  28. package/dist/esm/components/icons/HeatmapIcon.js +33 -0
  29. package/dist/esm/components/icons/MatrixPlotIcon.1.js +45 -0
  30. package/dist/esm/components/icons/MatrixPlotIcon.js +47 -0
  31. package/dist/esm/components/icons/ScatterplotIcon.1.js +152 -0
  32. package/dist/esm/components/icons/ScatterplotIcon.js +132 -0
  33. package/dist/esm/components/icons/ViolinPlotIcon.js +28 -0
  34. package/dist/esm/components/matrixplot/Matrixplot.js +24 -15
  35. package/dist/esm/components/pseudospatial/Pseudospatial.js +58 -18
  36. package/dist/esm/components/pseudospatial/PseudospatialToolbar.js +52 -4
  37. package/dist/esm/components/violin/Violin.js +36 -24
  38. package/dist/esm/context/DatasetContext.js +1 -1
  39. package/dist/esm/context/SettingsContext.js +27 -3
  40. package/dist/esm/utils/StyledTooltip.js +33 -0
  41. package/package.json +2 -2
  42. package/scss/cherita.scss +19 -1
  43. package/scss/components/layouts.scss +2 -21
  44. package/scss/components/plotly.scss +37 -26
  45. package/scss/components/plots.scss +14 -1
  46. package/dist/assets/images/plots/dotplot.svg +0 -152
  47. package/dist/assets/images/plots/heatmap.svg +0 -193
  48. package/dist/assets/images/plots/matrixplot.svg +0 -275
  49. package/dist/assets/images/plots/scatterplot.svg +0 -198
  50. package/dist/assets/images/plots/violin.svg +0 -50
@@ -4,16 +4,18 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.PseudospatialToolbar = PseudospatialToolbar;
7
- var _react = _interopRequireDefault(require("react"));
7
+ var _react = require("react");
8
+ var _material = require("@mui/material");
8
9
  var _lodash = _interopRequireDefault(require("lodash"));
9
10
  var _reactBootstrap = require("react-bootstrap");
10
11
  var _constants = require("../../constants/constants");
12
+ var _DatasetContext = require("../../context/DatasetContext");
11
13
  var _SettingsContext = require("../../context/SettingsContext");
12
14
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
13
15
  function CategoricalMode() {
14
16
  const settings = (0, _SettingsContext.useSettings)();
15
17
  const dispatch = (0, _SettingsContext.useSettingsDispatch)();
16
- const modeList = _lodash.default.map(_constants.PSEUDOSPATIAL_CATEGORICAL_MODES, (m, key) => /*#__PURE__*/_react.default.createElement(_reactBootstrap.Dropdown.Item, {
18
+ const modeList = _lodash.default.map(_constants.PSEUDOSPATIAL_CATEGORICAL_MODES, (m, key) => /*#__PURE__*/React.createElement(_reactBootstrap.Dropdown.Item, {
17
19
  key: key,
18
20
  active: settings.pseudospatial.categoricalMode === m,
19
21
  onClick: () => {
@@ -26,9 +28,9 @@ function CategoricalMode() {
26
28
  const mode = _lodash.default.find(_constants.PSEUDOSPATIAL_CATEGORICAL_MODES, {
27
29
  value: settings.pseudospatial.categoricalMode
28
30
  });
29
- return /*#__PURE__*/_react.default.createElement(_reactBootstrap.Dropdown, null, /*#__PURE__*/_react.default.createElement(_reactBootstrap.Dropdown.Toggle, {
31
+ return /*#__PURE__*/React.createElement(_reactBootstrap.Dropdown, null, /*#__PURE__*/React.createElement(_reactBootstrap.Dropdown.Toggle, {
30
32
  variant: "light"
31
- }, _lodash.default.capitalize(mode.name)), /*#__PURE__*/_react.default.createElement(_reactBootstrap.Dropdown.Menu, null, modeList));
33
+ }, _lodash.default.capitalize(mode.name)), /*#__PURE__*/React.createElement(_reactBootstrap.Dropdown.Menu, null, modeList));
32
34
  }
33
35
  function MaskSet() {
34
36
  var _settings$pseudospati5, _settings$pseudospati6, _maskSets$settings$ps2, _settings$pseudospati7, _settings$pseudospati8, _maskSets$settings$ps3, _settings$pseudospati9;
@@ -37,7 +39,7 @@ function MaskSet() {
37
39
  const {
38
40
  pseudospatial: maskSets
39
41
  } = settings.data;
40
- const maskSetList = _lodash.default.map(maskSets, (ms, key) => /*#__PURE__*/_react.default.createElement(_reactBootstrap.Dropdown.Item, {
42
+ const maskSetList = _lodash.default.map(maskSets, (ms, key) => /*#__PURE__*/React.createElement(_reactBootstrap.Dropdown.Item, {
41
43
  key: key,
42
44
  active: settings.pseudospatial.maskSet === key,
43
45
  onClick: () => {
@@ -73,9 +75,9 @@ function MaskSet() {
73
75
  });
74
76
  }
75
77
  };
76
- const masksList = _lodash.default.map(maskSets === null || maskSets === void 0 ? void 0 : maskSets[(_settings$pseudospati5 = settings.pseudospatial) === null || _settings$pseudospati5 === void 0 ? void 0 : _settings$pseudospati5.maskSet], mask => /*#__PURE__*/_react.default.createElement(_reactBootstrap.Dropdown.ItemText, {
78
+ const masksList = _lodash.default.map(maskSets === null || maskSets === void 0 ? void 0 : maskSets[(_settings$pseudospati5 = settings.pseudospatial) === null || _settings$pseudospati5 === void 0 ? void 0 : _settings$pseudospati5.maskSet], mask => /*#__PURE__*/React.createElement(_reactBootstrap.Dropdown.ItemText, {
77
79
  key: mask
78
- }, /*#__PURE__*/_react.default.createElement(_reactBootstrap.Form.Check, {
80
+ }, /*#__PURE__*/React.createElement(_reactBootstrap.Form.Check, {
79
81
  type: "checkbox",
80
82
  label: mask,
81
83
  checked: !settings.pseudospatial.maskValues || settings.pseudospatial.maskValues.includes(mask),
@@ -83,26 +85,72 @@ function MaskSet() {
83
85
  })));
84
86
  const nMasks = settings.pseudospatial.maskValues ? (_settings$pseudospati6 = settings.pseudospatial.maskValues) === null || _settings$pseudospati6 === void 0 ? void 0 : _settings$pseudospati6.length : (maskSets === null || maskSets === void 0 || (_maskSets$settings$ps2 = maskSets[(_settings$pseudospati7 = settings.pseudospatial) === null || _settings$pseudospati7 === void 0 ? void 0 : _settings$pseudospati7.maskSet]) === null || _maskSets$settings$ps2 === void 0 ? void 0 : _maskSets$settings$ps2.length) || "No";
85
87
  const toggleAllChecked = !settings.pseudospatial.maskValues || ((_settings$pseudospati8 = settings.pseudospatial.maskValues) === null || _settings$pseudospati8 === void 0 ? void 0 : _settings$pseudospati8.length) === (maskSets === null || maskSets === void 0 || (_maskSets$settings$ps3 = maskSets[(_settings$pseudospati9 = settings.pseudospatial) === null || _settings$pseudospati9 === void 0 ? void 0 : _settings$pseudospati9.maskSet]) === null || _maskSets$settings$ps3 === void 0 ? void 0 : _maskSets$settings$ps3.length);
86
- return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_reactBootstrap.Dropdown, null, /*#__PURE__*/_react.default.createElement(_reactBootstrap.Dropdown.Toggle, {
88
+ return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_reactBootstrap.Dropdown, null, /*#__PURE__*/React.createElement(_reactBootstrap.Dropdown.Toggle, {
87
89
  variant: "light"
88
- }, _lodash.default.capitalize(settings.pseudospatial.maskSet || "Select a mask set")), /*#__PURE__*/_react.default.createElement(_reactBootstrap.Dropdown.Menu, null, /*#__PURE__*/_react.default.createElement(_reactBootstrap.Dropdown.Header, null, "Mask set"), maskSetList)), /*#__PURE__*/_react.default.createElement(_reactBootstrap.Dropdown, null, /*#__PURE__*/_react.default.createElement(_reactBootstrap.Dropdown.Toggle, {
90
+ }, _lodash.default.capitalize(settings.pseudospatial.maskSet || "Select a mask set")), /*#__PURE__*/React.createElement(_reactBootstrap.Dropdown.Menu, null, /*#__PURE__*/React.createElement(_reactBootstrap.Dropdown.Header, null, "Mask set"), maskSetList)), /*#__PURE__*/React.createElement(_reactBootstrap.Dropdown, null, /*#__PURE__*/React.createElement(_reactBootstrap.Dropdown.Toggle, {
89
91
  variant: "light"
90
- }, nMasks, " masks selected"), /*#__PURE__*/_react.default.createElement(_reactBootstrap.Dropdown.Menu, null, /*#__PURE__*/_react.default.createElement(_reactBootstrap.Dropdown.Header, null, "Masks"), /*#__PURE__*/_react.default.createElement(_reactBootstrap.Dropdown.ItemText, {
92
+ }, nMasks, " masks selected"), /*#__PURE__*/React.createElement(_reactBootstrap.Dropdown.Menu, null, /*#__PURE__*/React.createElement(_reactBootstrap.Dropdown.Header, null, "Masks"), /*#__PURE__*/React.createElement(_reactBootstrap.Dropdown.ItemText, {
91
93
  key: "toggle-all"
92
- }, /*#__PURE__*/_react.default.createElement(_reactBootstrap.Form.Check, {
94
+ }, /*#__PURE__*/React.createElement(_reactBootstrap.Form.Check, {
93
95
  type: "checkbox",
94
96
  label: "Toggle all",
95
97
  checked: toggleAllChecked,
96
98
  onChange: toggleMasks
97
99
  })), masksList)));
98
100
  }
101
+ function OpacitySlider(_ref) {
102
+ let {
103
+ opacity,
104
+ setOpacity
105
+ } = _ref;
106
+ const [sliderValue, setSliderValue] = (0, _react.useState)(opacity);
107
+ return /*#__PURE__*/React.createElement(_material.Box, {
108
+ className: "w-100"
109
+ }, /*#__PURE__*/React.createElement(_material.Typography, {
110
+ id: "opacity-range",
111
+ gutterBottom: true
112
+ }, "Reference image opacity"), /*#__PURE__*/React.createElement("div", {
113
+ className: "px-4"
114
+ }, /*#__PURE__*/React.createElement(_material.Slider, {
115
+ "aria-labelledby": "opacity-range",
116
+ min: 0,
117
+ max: 1,
118
+ step: 0.05,
119
+ value: sliderValue,
120
+ onChange: (_e, value) => setSliderValue(value),
121
+ onChangeCommitted: (_e, value) => setOpacity(value),
122
+ valueLabelDisplay: "auto",
123
+ getAriaValueText: value => "".concat(value * 100, "%"),
124
+ valueLabelFormat: value => "".concat((value * 100).toFixed(0), "%"),
125
+ marks: [{
126
+ value: 0,
127
+ label: "0%"
128
+ }, {
129
+ value: 1,
130
+ label: "100%"
131
+ }]
132
+ })));
133
+ }
99
134
 
100
135
  // @TODO: add colormap, colorbar slider
101
- function PseudospatialToolbar(_ref) {
136
+ function PseudospatialToolbar(_ref2) {
102
137
  let {
103
138
  plotType
104
- } = _ref;
105
- return /*#__PURE__*/_react.default.createElement("div", {
139
+ } = _ref2;
140
+ const {
141
+ imageUrl
142
+ } = (0, _DatasetContext.useDataset)();
143
+ const settings = (0, _SettingsContext.useSettings)();
144
+ const dispatch = (0, _SettingsContext.useSettingsDispatch)();
145
+ return /*#__PURE__*/React.createElement("div", {
106
146
  className: "cherita-pseudospatial-toolbar"
107
- }, /*#__PURE__*/_react.default.createElement(_reactBootstrap.ButtonGroup, null, /*#__PURE__*/_react.default.createElement(MaskSet, null)), /*#__PURE__*/_react.default.createElement(_reactBootstrap.ButtonGroup, null, plotType === _constants.PSEUDOSPATIAL_PLOT_TYPES.CATEGORICAL && /*#__PURE__*/_react.default.createElement(CategoricalMode, null)));
147
+ }, /*#__PURE__*/React.createElement(_reactBootstrap.ButtonGroup, null, /*#__PURE__*/React.createElement(MaskSet, null)), /*#__PURE__*/React.createElement(_reactBootstrap.ButtonGroup, null, plotType === _constants.PSEUDOSPATIAL_PLOT_TYPES.CATEGORICAL && /*#__PURE__*/React.createElement(CategoricalMode, null)), imageUrl && /*#__PURE__*/React.createElement(OpacitySlider, {
148
+ opacity: settings.pseudospatial.refImg.opacity,
149
+ setOpacity: opacity => {
150
+ dispatch({
151
+ type: "set.pseudospatial.refImg.opacity",
152
+ opacity: opacity
153
+ });
154
+ }
155
+ }));
108
156
  }
@@ -4,7 +4,7 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.Violin = Violin;
7
- var _react = _interopRequireWildcard(require("react"));
7
+ var _react = require("react");
8
8
  var _freeSolidSvgIcons = require("@fortawesome/free-solid-svg-icons");
9
9
  var _reactFontawesome = require("@fortawesome/react-fontawesome");
10
10
  var _lodash = _interopRequireDefault(require("lodash"));
@@ -17,9 +17,10 @@ var _SettingsContext = require("../../context/SettingsContext");
17
17
  var _LoadingIndicators = require("../../utils/LoadingIndicators");
18
18
  var _requests = require("../../utils/requests");
19
19
  var _Resolver = require("../../utils/Resolver");
20
+ var _StyledTooltip = require("../../utils/StyledTooltip");
21
+ var _PlotAlert = require("../full-page/PlotAlert");
20
22
  var _Toolbar = require("../toolbar/Toolbar");
21
23
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
22
- 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); }
23
24
  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; }
24
25
  function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
25
26
  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; }
@@ -33,7 +34,9 @@ function Violin(_ref) {
33
34
  showCtrlsBtn = false,
34
35
  setShowObs,
35
36
  setShowVars,
36
- setShowControls
37
+ setShowControls,
38
+ plotType,
39
+ setPlotType
37
40
  } = _ref;
38
41
  const ENDPOINT = "violin";
39
42
  const dataset = (0, _DatasetContext.useDataset)();
@@ -138,16 +141,16 @@ function Violin(_ref) {
138
141
  const modeBarButtons = customModeBarButtons.length ? [customModeBarButtons, _constants.PLOTLY_MODEBAR_BUTTONS] : [_constants.PLOTLY_MODEBAR_BUTTONS];
139
142
  if (!serverError) {
140
143
  if (hasSelections) {
141
- return /*#__PURE__*/_react.default.createElement("div", {
144
+ return /*#__PURE__*/React.createElement("div", {
142
145
  className: "cherita-plot cherita-violin"
143
- }, isPending && /*#__PURE__*/_react.default.createElement(_LoadingIndicators.LoadingSpinner, null), /*#__PURE__*/_react.default.createElement("div", {
146
+ }, isPending && /*#__PURE__*/React.createElement(_LoadingIndicators.LoadingSpinner, null), /*#__PURE__*/React.createElement("div", {
144
147
  className: "d-flex flex-column h-100"
145
- }, /*#__PURE__*/_react.default.createElement("div", {
148
+ }, /*#__PURE__*/React.createElement("div", {
146
149
  className: "flex-grow-1 position-relative",
147
150
  style: {
148
151
  minHeight: "0"
149
152
  }
150
- }, /*#__PURE__*/_react.default.createElement(_reactPlotly.default, {
153
+ }, /*#__PURE__*/React.createElement(_reactPlotly.default, {
151
154
  data: data,
152
155
  layout: layout,
153
156
  useResizeHandler: true,
@@ -159,40 +162,48 @@ function Violin(_ref) {
159
162
  displaylogo: false,
160
163
  modeBarButtons: modeBarButtons
161
164
  }
162
- })), (fetchedData === null || fetchedData === void 0 ? void 0 : fetchedData.resampled) && /*#__PURE__*/_react.default.createElement("div", {
163
- className: "flex-shrink-0"
164
- }, /*#__PURE__*/_react.default.createElement(_reactBootstrap.Alert, {
165
- variant: "warning",
166
- className: "mb-1"
167
- }, /*#__PURE__*/_react.default.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.default.createElement(_reactBootstrap.OverlayTrigger, {
168
- placement: "top",
169
- overlay: /*#__PURE__*/_react.default.createElement(_reactBootstrap.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.")
170
- }, /*#__PURE__*/_react.default.createElement(_reactFontawesome.FontAwesomeIcon, {
165
+ })), (fetchedData === null || fetchedData === void 0 ? void 0 : fetchedData.resampled) && /*#__PURE__*/React.createElement("div", {
166
+ className: "resampled-tooltip-container"
167
+ }, /*#__PURE__*/React.createElement(_StyledTooltip.StyledTooltip, {
168
+ title: /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("strong", null, "Note:"), " 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."),
169
+ placement: "bottom"
170
+ }, /*#__PURE__*/React.createElement(_reactBootstrap.Badge, {
171
+ bg: "info"
172
+ }, /*#__PURE__*/React.createElement(_reactFontawesome.FontAwesomeIcon, {
173
+ className: "fs-6",
171
174
  icon: _freeSolidSvgIcons.faCircleInfo
172
- }))))));
175
+ }), /*#__PURE__*/React.createElement("span", {
176
+ className: "d-none d-lg-inline ms-2 fs-6 text-uppercase"
177
+ }, "Resampled"))))));
173
178
  }
174
- return /*#__PURE__*/_react.default.createElement("div", {
175
- className: "cherita-violin"
176
- }, mode === _constants.VIOLIN_MODES.MULTIKEY && /*#__PURE__*/_react.default.createElement(_reactBootstrap.Alert, {
177
- variant: "light"
178
- }, "Select", " ", showVarsBtn ? /*#__PURE__*/_react.default.createElement(_reactBootstrap.Button, {
179
+ return /*#__PURE__*/React.createElement(_PlotAlert.PlotAlert, {
180
+ variant: "info",
181
+ heading: "Violin plot",
182
+ plotType: plotType,
183
+ setPlotType: setPlotType
184
+ }, mode === _constants.VIOLIN_MODES.MULTIKEY && /*#__PURE__*/React.createElement("p", {
185
+ className: "p-0 m-0"
186
+ }, "To begin, select one or more", " ", showVarsBtn ? /*#__PURE__*/React.createElement(_reactBootstrap.Button, {
179
187
  variant: "link",
180
188
  className: "border-0 p-0 align-baseline",
181
189
  onClick: setShowVars
182
- }, "features") : "features"), mode === _constants.VIOLIN_MODES.GROUPBY && /*#__PURE__*/_react.default.createElement(_reactBootstrap.Alert, {
183
- variant: "light"
184
- }, "Select", " ", showObsBtn ? /*#__PURE__*/_react.default.createElement(_reactBootstrap.Button, {
190
+ }, "features") : "features", " ", "to display their expression distributions across all observations."), mode === _constants.VIOLIN_MODES.GROUPBY && /*#__PURE__*/React.createElement("p", {
191
+ className: "p-0 m-0"
192
+ }, "To begin, select a", " ", showObsBtn ? /*#__PURE__*/React.createElement(_reactBootstrap.Button, {
185
193
  variant: "link",
186
194
  className: "border-0 p-0 align-baseline",
187
195
  onClick: setShowObs
188
- }, "categories") : "categories", " ", "and a", " ", showVarsBtn ? /*#__PURE__*/_react.default.createElement(_reactBootstrap.Button, {
196
+ }, "category") : "category", " ", "to group observations, and choose a", " ", showVarsBtn ? /*#__PURE__*/React.createElement(_reactBootstrap.Button, {
189
197
  variant: "link",
190
198
  className: "border-0 p-0 align-baseline",
191
199
  onClick: setShowVars
192
- }, "feature") : "feature"));
200
+ }, "feature") : "feature", " ", "to view its distribution within each group."));
193
201
  } else {
194
- return /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement(_reactBootstrap.Alert, {
195
- variant: "danger"
196
- }, serverError.message));
202
+ return /*#__PURE__*/React.createElement(_PlotAlert.PlotAlert, {
203
+ variant: "danger",
204
+ heading: "Violin plot",
205
+ plotType: plotType,
206
+ setPlotType: setPlotType
207
+ }, serverError.message || "An unexpected error occurred while generating the plot.");
197
208
  }
198
209
  }
@@ -60,7 +60,7 @@ const persistOptions = {
60
60
  return false;
61
61
  }
62
62
  },
63
- buster: "1.4.1-dev.2025-10-20.528e0f75" || "0.0.0"
63
+ buster: "1.4.1-dev.2025-10-22.61540191" || "0.0.0"
64
64
  // @TODO: add maxAge and api version numbers as buster
65
65
  };
66
66
  const initialDataset = {
@@ -73,7 +73,11 @@ const initialSettings = {
73
73
  pseudospatial: {
74
74
  maskSet: null,
75
75
  maskValues: null,
76
- categoricalMode: _constants.PSEUDOSPATIAL_CATEGORICAL_MODES.ACROSS.value
76
+ categoricalMode: _constants.PSEUDOSPATIAL_CATEGORICAL_MODES.ACROSS.value,
77
+ refImg: {
78
+ visible: false,
79
+ opacity: 1
80
+ }
77
81
  },
78
82
  // dataset resolved values
79
83
  data: {
@@ -169,7 +173,7 @@ function SettingsProvider(_ref2) {
169
173
 
170
174
  // If the buster is not set or does not match the current package version,
171
175
  // reset localSettings to avoid stale data
172
- if (!buster || buster !== "1.4.1-dev.2025-10-20.528e0f75") {
176
+ if (!buster || buster !== "1.4.1-dev.2025-10-22.61540191") {
173
177
  localSettings = {};
174
178
  }
175
179
  const initSettings = (0, _react.useRef)(initializer({
@@ -194,7 +198,7 @@ function SettingsProvider(_ref2) {
194
198
  if (canOverrideSettings && settings) {
195
199
  try {
196
200
  localStorage.setItem(DATASET_STORAGE_KEY, JSON.stringify(_objectSpread({
197
- buster: "1.4.1-dev.2025-10-20.528e0f75" || "0.0.0",
201
+ buster: "1.4.1-dev.2025-10-22.61540191" || "0.0.0",
198
202
  timestamp: Date.now()
199
203
  }, _lodash.default.omit(settings, "data"))));
200
204
  } catch (err) {
@@ -719,6 +723,26 @@ function settingsReducer(settings, action) {
719
723
  })
720
724
  });
721
725
  }
726
+ case "toggle.pseudospatial.refImg.visible":
727
+ {
728
+ return _objectSpread(_objectSpread({}, settings), {}, {
729
+ pseudospatial: _objectSpread(_objectSpread({}, settings.pseudospatial), {}, {
730
+ refImg: _objectSpread(_objectSpread({}, settings.pseudospatial.refImg), {}, {
731
+ visible: !settings.pseudospatial.refImg.visible
732
+ })
733
+ })
734
+ });
735
+ }
736
+ case "set.pseudospatial.refImg.opacity":
737
+ {
738
+ return _objectSpread(_objectSpread({}, settings), {}, {
739
+ pseudospatial: _objectSpread(_objectSpread({}, settings.pseudospatial), {}, {
740
+ refImg: _objectSpread(_objectSpread({}, settings.pseudospatial.refImg), {}, {
741
+ opacity: action.opacity
742
+ })
743
+ })
744
+ });
745
+ }
722
746
  default:
723
747
  {
724
748
  throw Error("Unknown action: " + action.type);
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.StyledTooltip = void 0;
7
+ var _material = require("@mui/material");
8
+ const _excluded = ["className"];
9
+ function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
10
+ 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; }
11
+ 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; }
12
+ const StyledTooltip = exports.StyledTooltip = (0, _material.styled)(_ref => {
13
+ let {
14
+ className
15
+ } = _ref,
16
+ props = _objectWithoutProperties(_ref, _excluded);
17
+ return /*#__PURE__*/React.createElement(_material.Tooltip, _extends({}, props, {
18
+ classes: {
19
+ popper: className
20
+ }
21
+ }));
22
+ })(_ref2 => {
23
+ let {
24
+ theme
25
+ } = _ref2;
26
+ return {
27
+ ["& .".concat(_material.tooltipClasses.tooltip)]: {
28
+ backgroundColor: "#000",
29
+ color: "#fff",
30
+ maxWidth: 220,
31
+ fontSize: 13,
32
+ borderRadius: 4,
33
+ padding: theme.spacing(0.5, 1),
34
+ whiteSpace: "pre-line",
35
+ textAlign: "center",
36
+ boxShadow: "0 0.25rem 0.75rem rgba(0, 0, 0, 0.1)"
37
+ }
38
+ };
39
+ });
@@ -7988,11 +7988,11 @@ textarea.form-control-lg {
7988
7988
  margin-left: auto !important;
7989
7989
  }
7990
7990
 
7991
- .p-0, .cherita-app-sidebar .card-body, .cherita-app-container {
7991
+ .p-0, .cherita-app-sidebar .card-body, .cherita-app-container, .cherita-app-container .cherita-app-canvas {
7992
7992
  padding: 0 !important;
7993
7993
  }
7994
7994
 
7995
- .p-1, .cherita-app-container .cherita-app-canvas {
7995
+ .p-1 {
7996
7996
  padding: 0.25rem !important;
7997
7997
  }
7998
7998
 
@@ -12004,19 +12004,6 @@ textarea.form-control-lg {
12004
12004
  transform: var(--geeks-accordion-btn-icon-transform);
12005
12005
  }
12006
12006
 
12007
- .sidebar-plotselector {
12008
- padding: 6px;
12009
- border-bottom: 1px solid #dee2e6;
12010
- }
12011
- .sidebar-plotselector .plotselector-icon {
12012
- padding-bottom: 2px;
12013
- cursor: pointer;
12014
- }
12015
- .sidebar-plotselector .plotselector-icon .active {
12016
- opacity: 1;
12017
- border-bottom: 2px solid #007bff;
12018
- }
12019
-
12020
12007
  .sidebar-pseudospatial {
12021
12008
  padding: 10px;
12022
12009
  border-bottom: 1px solid #dee2e6;
@@ -12070,7 +12057,7 @@ textarea.form-control-lg {
12070
12057
  }
12071
12058
  .cherita-app-container .cherita-app-canvas {
12072
12059
  flex: 1 1 auto;
12073
- min-width: 400px;
12060
+ min-width: 375px;
12074
12061
  position: relative;
12075
12062
  max-height: 100%;
12076
12063
  display: flex;
@@ -12092,10 +12079,10 @@ textarea.form-control-lg {
12092
12079
  }
12093
12080
  }
12094
12081
 
12095
- .ps-xs-1 {
12096
- padding-left: 0.15rem !important;
12082
+ .js-plotly-plot .plotly .modebar {
12083
+ top: 16px;
12084
+ right: 0;
12097
12085
  }
12098
-
12099
12086
  .js-plotly-plot .plotly .modebar .modebar-group {
12100
12087
  border-radius: 5px;
12101
12088
  padding: 4px !important;
@@ -12103,6 +12090,7 @@ textarea.form-control-lg {
12103
12090
  .js-plotly-plot .plotly .modebar .modebar-group .modebar-btn {
12104
12091
  display: inline-flex;
12105
12092
  justify-content: center;
12093
+ align-items: center;
12106
12094
  position: relative;
12107
12095
  font-size: 1.25rem;
12108
12096
  padding: 0.25rem;
@@ -12118,17 +12106,16 @@ textarea.form-control-lg {
12118
12106
  fill: white !important;
12119
12107
  color: white !important;
12120
12108
  }
12121
-
12122
12109
  .js-plotly-plot .plotly .modebar--hover > :not(.watermark) {
12123
- opacity: 0.5;
12110
+ opacity: 1;
12124
12111
  transition: opacity 0.3s;
12125
12112
  }
12126
12113
 
12127
12114
  .cherita-spatial-controls {
12128
12115
  position: absolute;
12129
- z-index: 10;
12130
12116
  top: 1rem;
12131
12117
  left: 1rem;
12118
+ z-index: 10;
12132
12119
  width: 3rem;
12133
12120
  }
12134
12121
  .cherita-spatial-controls .btn {
@@ -12136,6 +12123,15 @@ textarea.form-control-lg {
12136
12123
  padding-right: 0;
12137
12124
  }
12138
12125
 
12126
+ .plotselector {
12127
+ padding: 0 10px;
12128
+ border-bottom: 1px solid #dee2e6;
12129
+ }
12130
+ .plotselector .plotselector-icon {
12131
+ padding: 6px;
12132
+ cursor: pointer;
12133
+ }
12134
+
12139
12135
  .modern-scrollbars::-webkit-scrollbar {
12140
12136
  width: 20px;
12141
12137
  }
@@ -12546,4 +12542,23 @@ input[type=checkbox] {
12546
12542
  cursor: pointer;
12547
12543
  }
12548
12544
 
12545
+ .ps-xs-1 {
12546
+ padding-left: 0.15rem !important;
12547
+ }
12548
+
12549
+ .resampled-tooltip-container {
12550
+ position: absolute;
12551
+ bottom: 16px;
12552
+ right: 16px;
12553
+ z-index: 10;
12554
+ width: max-content;
12555
+ }
12556
+ @media (min-width: 991px) {
12557
+ .resampled-tooltip-container {
12558
+ top: 16px;
12559
+ left: 16px;
12560
+ bottom: auto;
12561
+ }
12562
+ }
12563
+
12549
12564
  /*# sourceMappingURL=cherita.css.map */