@haniffalab/cherita-react 1.3.0 → 1.4.0-dev.2025-06-09.09fbcbf5

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 (49) hide show
  1. package/dist/assets/images/plots/dotplot.svg +152 -0
  2. package/dist/assets/images/plots/heatmap.svg +193 -0
  3. package/dist/assets/images/plots/matrixplot.svg +275 -0
  4. package/dist/assets/images/plots/scatterplot.svg +198 -0
  5. package/dist/assets/images/plots/violin.svg +50 -0
  6. package/dist/cjs/components/dotplot/Dotplot.js +35 -5
  7. package/dist/cjs/components/full-page/FullPage.js +109 -50
  8. package/dist/cjs/components/full-page/PlotTypeSelector.js +57 -0
  9. package/dist/cjs/components/heatmap/Heatmap.js +35 -5
  10. package/dist/cjs/components/matrixplot/Matrixplot.js +35 -5
  11. package/dist/cjs/components/obs-list/ObsItem.js +49 -22
  12. package/dist/cjs/components/obs-list/ObsList.js +9 -5
  13. package/dist/cjs/components/scatterplot/Scatterplot.js +115 -95
  14. package/dist/cjs/components/scatterplot/SpatialControls.js +3 -3
  15. package/dist/cjs/components/search-bar/SearchInfo.js +3 -35
  16. package/dist/cjs/components/toolbar/Toolbar.js +102 -0
  17. package/dist/cjs/components/var-list/VarList.js +11 -3
  18. package/dist/cjs/components/violin/Violin.js +37 -6
  19. package/dist/cjs/constants/constants.js +14 -2
  20. package/dist/cjs/context/DatasetContext.js +2 -1
  21. package/dist/cjs/context/SettingsContext.js +77 -46
  22. package/dist/cjs/helpers/map-helper.js +2 -1
  23. package/dist/cjs/index.js +15 -21
  24. package/dist/css/cherita.css +76 -23
  25. package/dist/css/cherita.css.map +1 -1
  26. package/dist/esm/components/dotplot/Dotplot.js +36 -6
  27. package/dist/esm/components/full-page/FullPage.js +111 -50
  28. package/dist/esm/components/full-page/PlotTypeSelector.js +50 -0
  29. package/dist/esm/components/heatmap/Heatmap.js +36 -6
  30. package/dist/esm/components/matrixplot/Matrixplot.js +36 -6
  31. package/dist/esm/components/obs-list/ObsItem.js +49 -22
  32. package/dist/esm/components/obs-list/ObsList.js +9 -5
  33. package/dist/esm/components/scatterplot/Scatterplot.js +115 -95
  34. package/dist/esm/components/scatterplot/SpatialControls.js +3 -3
  35. package/dist/esm/components/search-bar/SearchInfo.js +1 -33
  36. package/dist/esm/components/toolbar/Toolbar.js +91 -0
  37. package/dist/esm/components/var-list/VarList.js +10 -5
  38. package/dist/esm/components/violin/Violin.js +39 -8
  39. package/dist/esm/constants/constants.js +13 -1
  40. package/dist/esm/context/DatasetContext.js +2 -1
  41. package/dist/esm/context/SettingsContext.js +77 -46
  42. package/dist/esm/helpers/map-helper.js +2 -1
  43. package/dist/esm/index.js +4 -4
  44. package/package.json +6 -4
  45. package/scss/cherita.scss +0 -1
  46. package/scss/components/layouts.scss +69 -1
  47. package/scss/components/plotly.scss +19 -14
  48. package/dist/cjs/components/full-page/FullPagePseudospatial.js +0 -157
  49. package/dist/esm/components/full-page/FullPagePseudospatial.js +0 -149
@@ -16,6 +16,7 @@ var _FilterContext = require("../../context/FilterContext");
16
16
  var _SettingsContext = require("../../context/SettingsContext");
17
17
  var _LoadingIndicators = require("../../utils/LoadingIndicators");
18
18
  var _requests = require("../../utils/requests");
19
+ var _Toolbar = require("../toolbar/Toolbar");
19
20
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
20
21
  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); }
21
22
  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; }
@@ -26,7 +27,13 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
26
27
  function Violin(_ref) {
27
28
  var _settings$selectedVar, _settings$selectedVar2, _settings$selectedVar3, _settings$selectedVar4, _settings$selectedObs, _settings$selectedObs2, _settings$selectedObs3;
28
29
  let {
29
- mode = _constants.VIOLIN_MODES.MULTIKEY
30
+ mode = _constants.VIOLIN_MODES.MULTIKEY,
31
+ showObsBtn = false,
32
+ showVarsBtn = false,
33
+ showCtrlsBtn = false,
34
+ setShowObs,
35
+ setShowVars,
36
+ setShowControls
30
37
  } = _ref;
31
38
  const ENDPOINT = "violin";
32
39
  const dataset = (0, _DatasetContext.useDataset)();
@@ -125,17 +132,29 @@ function Violin(_ref) {
125
132
  setLayout(fetchedData.layout);
126
133
  }
127
134
  }, [fetchedData, hasSelections, isPending, serverError]);
135
+ const customModeBarButtons = _lodash.default.compact([showObsBtn && (0, _Toolbar.ObsPlotlyToolbar)({
136
+ onClick: setShowObs
137
+ }), showVarsBtn && (0, _Toolbar.VarPlotlyToolbar)({
138
+ onClick: setShowVars
139
+ }), showCtrlsBtn && (0, _Toolbar.ControlsPlotlyToolbar)({
140
+ onClick: setShowControls
141
+ })]);
142
+ const modeBarButtons = customModeBarButtons.length ? [customModeBarButtons, _constants.PLOTLY_MODEBAR_BUTTONS] : [_constants.PLOTLY_MODEBAR_BUTTONS];
128
143
  if (!serverError) {
129
144
  if (hasSelections) {
130
145
  return /*#__PURE__*/_react.default.createElement("div", {
131
- className: "cherita-violin position-relative"
146
+ className: "cherita-plot cherita-violin position-relative"
132
147
  }, isPending && /*#__PURE__*/_react.default.createElement(_LoadingIndicators.LoadingSpinner, null), /*#__PURE__*/_react.default.createElement(_reactPlotly.default, {
133
148
  data: data,
134
149
  layout: layout,
135
150
  useResizeHandler: true,
136
151
  style: {
137
- maxWidth: "100%",
138
- maxHeight: "100%"
152
+ width: "100%",
153
+ height: "100%"
154
+ },
155
+ config: {
156
+ displaylogo: false,
157
+ modeBarButtons: modeBarButtons
139
158
  }
140
159
  }), (fetchedData === null || fetchedData === void 0 ? void 0 : fetchedData.resampled) && /*#__PURE__*/_react.default.createElement(_reactBootstrap.Alert, {
141
160
  variant: "warning"
@@ -150,9 +169,21 @@ function Violin(_ref) {
150
169
  className: "cherita-violin"
151
170
  }, mode === _constants.VIOLIN_MODES.MULTIKEY && /*#__PURE__*/_react.default.createElement(_reactBootstrap.Alert, {
152
171
  variant: "light"
153
- }, "Select features"), mode === _constants.VIOLIN_MODES.GROUPBY && /*#__PURE__*/_react.default.createElement(_reactBootstrap.Alert, {
172
+ }, "Select", " ", showVarsBtn ? /*#__PURE__*/_react.default.createElement(_reactBootstrap.Button, {
173
+ variant: "link",
174
+ className: "border-0 p-0 align-baseline",
175
+ onClick: setShowVars
176
+ }, "features") : "features"), mode === _constants.VIOLIN_MODES.GROUPBY && /*#__PURE__*/_react.default.createElement(_reactBootstrap.Alert, {
154
177
  variant: "light"
155
- }, "Select categories and a feature"));
178
+ }, "Select", " ", showObsBtn ? /*#__PURE__*/_react.default.createElement(_reactBootstrap.Button, {
179
+ variant: "link",
180
+ className: "border-0 p-0 align-baseline",
181
+ onClick: setShowObs
182
+ }, "categories") : "categories", " ", "and a", " ", showVarsBtn ? /*#__PURE__*/_react.default.createElement(_reactBootstrap.Button, {
183
+ variant: "link",
184
+ className: "border-0 p-0 align-baseline",
185
+ onClick: setShowVars
186
+ }, "feature") : "feature"));
156
187
  } else {
157
188
  return /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement(_reactBootstrap.Alert, {
158
189
  variant: "danger"
@@ -3,8 +3,15 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.VIOLIN_MODES = exports.VIOLINPLOT_SCALES = exports.VAR_SORT_ORDER = exports.VAR_SORT = exports.UNSELECTED_POLYGON_FILLCOLOR = exports.SELECTION_MODES = exports.SELECTED_POLYGON_FILLCOLOR = exports.PSEUDOSPATIAL_PLOT_TYPES = exports.PSEUDOSPATIAL_CATEGORICAL_MODES = exports.OBS_TYPES = exports.MATRIXPLOT_SCALES = exports.LOCAL_STORAGE_KEY = exports.DOTPLOT_SCALES = exports.DEFAULT_OBS_GROUP = exports.COLOR_ENCODINGS = void 0;
6
+ exports.VIOLIN_MODES = exports.VIOLINPLOT_SCALES = exports.VAR_SORT_ORDER = exports.VAR_SORT = exports.UNSELECTED_POLYGON_FILLCOLOR = exports.SELECTION_MODES = exports.SELECTED_POLYGON_FILLCOLOR = exports.PSEUDOSPATIAL_PLOT_TYPES = exports.PSEUDOSPATIAL_CATEGORICAL_MODES = exports.PLOT_TYPES = exports.PLOTLY_MODEBAR_BUTTONS = exports.OBS_TYPES = exports.MATRIXPLOT_SCALES = exports.LOCAL_STORAGE_KEY = exports.DOTPLOT_SCALES = exports.DEFAULT_OBS_GROUP = exports.COLOR_ENCODINGS = exports.BREAKPOINTS = void 0;
7
7
  const LOCAL_STORAGE_KEY = exports.LOCAL_STORAGE_KEY = "CHERITA";
8
+ const PLOT_TYPES = exports.PLOT_TYPES = {
9
+ SCATTERPLOT: "scatterplot",
10
+ DOTPLOT: "dotplot",
11
+ HEATMAP: "heatmap",
12
+ MATRIXPLOT: "matrixplot",
13
+ VIOLINPLOT: "violinplot"
14
+ };
8
15
  const COLOR_ENCODINGS = exports.COLOR_ENCODINGS = {
9
16
  VAR: "var",
10
17
  OBS: "obs"
@@ -91,4 +98,9 @@ const PSEUDOSPATIAL_CATEGORICAL_MODES = exports.PSEUDOSPATIAL_CATEGORICAL_MODES
91
98
 
92
99
  // `default` cols to be shown out of accordion, at top of obslist
93
100
  // default values from cellxgene schema
94
- const DEFAULT_OBS_GROUP = exports.DEFAULT_OBS_GROUP = ["assay", "cell_type", "development_stage", "disease", "donor_id", "organism", "self_reported_ethnicity", "sex", "suspension_type", "tissue", "tissue_type"];
101
+ const DEFAULT_OBS_GROUP = exports.DEFAULT_OBS_GROUP = ["assay", "cell_type", "development_stage", "disease", "donor_id", "organism", "self_reported_ethnicity", "sex", "suspension_type", "tissue", "tissue_type"];
102
+ const PLOTLY_MODEBAR_BUTTONS = exports.PLOTLY_MODEBAR_BUTTONS = ["toImage", "zoom2d", "pan2d", "zoomIn2d", "zoomOut2d", "autoScale2d", "resetScale2d"];
103
+ const BREAKPOINTS = exports.BREAKPOINTS = {
104
+ LG: "(max-width: 991.98px)",
105
+ XL: "(max-width: 1199.98px)"
106
+ };
@@ -69,7 +69,8 @@ const initialDataset = {
69
69
  obsGroups: null,
70
70
  imageUrl: null,
71
71
  defaultSettings: {},
72
- canOverrideSettings: true
72
+ canOverrideSettings: true,
73
+ useUnsColors: false
73
74
  };
74
75
  function DatasetProvider(_ref2) {
75
76
  let {
@@ -19,6 +19,11 @@ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol"
19
19
  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); }
20
20
  const SettingsContext = exports.SettingsContext = /*#__PURE__*/(0, _react.createContext)(null);
21
21
  const SettingsDispatchContext = exports.SettingsDispatchContext = /*#__PURE__*/(0, _react.createContext)(null);
22
+
23
+ // @TODO: consider splitting constant values and dataset-resolved values
24
+ // e.g. store only obs name in selectedObs, and resolved obs data (counts, values, etc.) elsewhere
25
+ // e.g. store only var name in selectedVar, and resolved var data (index, matrix_index) elsewhere
26
+ // would simplify passing and validating defaultSettings and localSettings
22
27
  const initialSettings = {
23
28
  selectedObs: null,
24
29
  selectedVar: null,
@@ -67,13 +72,51 @@ const initialSettings = {
67
72
  categoricalMode: _constants.PSEUDOSPATIAL_CATEGORICAL_MODES.ACROSS.value
68
73
  }
69
74
  };
75
+
76
+ // validate on initialization and reducer
77
+ const validateSettings = settings => {
78
+ // make sure selectedVar is in vars
79
+ if (settings.selectedVar) {
80
+ const inVars = _lodash.default.some(settings.vars, v => v.name === settings.selectedVar.name);
81
+ if (!inVars) {
82
+ settings.vars = [...settings.vars, settings.selectedVar];
83
+ }
84
+ }
85
+
86
+ // make sure selectedMultiVar are in vars
87
+ if (settings.selectedMultiVar) {
88
+ const notInVars = _lodash.default.differenceBy(settings.selectedMultiVar, settings.vars, "name");
89
+ if (notInVars.length) {
90
+ settings.vars = [...settings.vars, ...notInVars];
91
+ }
92
+ }
93
+
94
+ // make sure there's a selectedVar if colorEncoding is VAR
95
+ if (settings.colorEncoding === _constants.COLOR_ENCODINGS.VAR) {
96
+ if (!settings.selectedVar) {
97
+ settings.colorEncoding = null;
98
+ } else if (settings.selectedVar.isSet && !settings.selectedVar.vars.length) {
99
+ settings.selectedVar = null;
100
+ settings.colorEncoding = null;
101
+ }
102
+ }
103
+
104
+ // make sure there's a selectedObs if colorEncoding is OBS
105
+ if (settings.colorEncoding === _constants.COLOR_ENCODINGS.OBS) {
106
+ if (!settings.selectedObs) {
107
+ settings.colorEncoding = null;
108
+ }
109
+ }
110
+ return settings;
111
+ };
70
112
  const initializer = _ref => {
71
113
  let {
72
114
  canOverrideSettings,
73
115
  defaultSettings,
74
116
  localSettings
75
117
  } = _ref;
76
- return canOverrideSettings ? _lodash.default.assign({}, initialSettings, defaultSettings, localSettings) : _lodash.default.assign({}, initialSettings, defaultSettings);
118
+ const mergedSettings = canOverrideSettings ? _lodash.default.assign({}, initialSettings, defaultSettings, localSettings) : _lodash.default.assign({}, initialSettings, defaultSettings);
119
+ return validateSettings(mergedSettings);
77
120
  };
78
121
  function SettingsProvider(_ref2) {
79
122
  let {
@@ -140,77 +183,65 @@ function settingsReducer(settings, action) {
140
183
  }
141
184
  case "select.var":
142
185
  {
143
- if (settings.vars.find(v => _lodash.default.isEqual(v, action.var))) {
144
- return _objectSpread(_objectSpread({}, settings), {}, {
145
- selectedVar: action.var
146
- });
147
- } else {
148
- return _objectSpread(_objectSpread({}, settings), {}, {
149
- selectedVar: action.var,
150
- vars: [...settings.vars, action.var]
151
- });
152
- }
186
+ return validateSettings(_objectSpread(_objectSpread({}, settings), {}, {
187
+ selectedVar: action.var
188
+ }));
153
189
  }
154
190
  case "select.multivar":
155
191
  {
156
- const vars = settings.vars.find(v => _lodash.default.isEqual(v, action.var)) ? settings.vars : [...settings.vars, action.var];
157
- if (settings.selectedMultiVar.find(v => _lodash.default.isEqual(v, action.var))) {
158
- return _objectSpread(_objectSpread({}, settings), {}, {
159
- vars: vars
160
- });
192
+ const inMultiVar = settings.selectedMultiVar.some(v => v.name === action.var.name);
193
+ if (inMultiVar) {
194
+ return validateSettings(_objectSpread({}, settings));
161
195
  } else {
162
- return _objectSpread(_objectSpread({}, settings), {}, {
163
- selectedMultiVar: [...settings.selectedMultiVar, action.var],
164
- vars: vars
165
- });
196
+ return validateSettings(_objectSpread(_objectSpread({}, settings), {}, {
197
+ selectedMultiVar: [...settings.selectedMultiVar, action.var]
198
+ }));
166
199
  }
167
200
  }
168
201
  case "deselect.multivar":
169
202
  {
170
- return _objectSpread(_objectSpread({}, settings), {}, {
203
+ return validateSettings(_objectSpread(_objectSpread({}, settings), {}, {
171
204
  selectedMultiVar: settings.selectedMultiVar.filter(v => v !== action.var.name)
172
- });
205
+ }));
173
206
  }
174
207
  case "toggle.multivar":
175
208
  {
176
209
  const inMultiVar = settings.selectedMultiVar.some(v => v.name === action.var.name);
177
210
  if (inMultiVar) {
178
- return _objectSpread(_objectSpread({}, settings), {}, {
211
+ return validateSettings(_objectSpread(_objectSpread({}, settings), {}, {
179
212
  selectedMultiVar: settings.selectedMultiVar.filter(v => v.name !== action.var.name)
180
- });
213
+ }));
181
214
  } else {
182
- return _objectSpread(_objectSpread({}, settings), {}, {
215
+ return validateSettings(_objectSpread(_objectSpread({}, settings), {}, {
183
216
  selectedMultiVar: [...settings.selectedMultiVar, action.var]
184
- });
217
+ }));
185
218
  }
186
219
  }
187
220
  case "set.colorEncoding":
188
221
  {
189
- return _objectSpread(_objectSpread({}, settings), {}, {
222
+ return validateSettings(_objectSpread(_objectSpread({}, settings), {}, {
190
223
  colorEncoding: action.value
191
- });
224
+ }));
192
225
  }
193
226
  case "reset.vars":
194
227
  {
195
- return _objectSpread(_objectSpread({}, settings), {}, {
228
+ return validateSettings(_objectSpread(_objectSpread({}, settings), {}, {
196
229
  vars: [],
197
230
  selectedVar: null,
198
231
  selectedMultiVar: []
199
- });
232
+ }));
200
233
  }
201
234
  case "reset.multiVar":
202
235
  {
203
- return _objectSpread(_objectSpread({}, settings), {}, {
204
- selectedMultiVar: [],
205
- colorEncoding: settings.colorEncoding === _constants.COLOR_ENCODINGS.VAR ? null : settings.colorEncoding
206
- });
236
+ return validateSettings(_objectSpread(_objectSpread({}, settings), {}, {
237
+ selectedMultiVar: []
238
+ }));
207
239
  }
208
240
  case "reset.var":
209
241
  {
210
- return _objectSpread(_objectSpread({}, settings), {}, {
211
- selectedVar: null,
212
- colorEncoding: settings.colorEncoding === _constants.COLOR_ENCODINGS.VAR ? null : settings.colorEncoding
213
- });
242
+ return validateSettings(_objectSpread(_objectSpread({}, settings), {}, {
243
+ selectedVar: null
244
+ }));
214
245
  }
215
246
  case "add.var":
216
247
  {
@@ -227,11 +258,11 @@ function settingsReducer(settings, action) {
227
258
  var _settings$selectedVar;
228
259
  const selectedVar = ((_settings$selectedVar = settings.selectedVar) === null || _settings$selectedVar === void 0 ? void 0 : _settings$selectedVar.name) === action.var.name ? null : settings.selectedVar;
229
260
  const selectedMultiVar = settings.selectedMultiVar.filter(v => v.name !== action.var.name);
230
- return _objectSpread(_objectSpread({}, settings), {}, {
261
+ return validateSettings(_objectSpread(_objectSpread({}, settings), {}, {
231
262
  vars: settings.vars.filter(a => a.name !== action.var.name),
232
263
  selectedVar: selectedVar,
233
264
  selectedMultiVar: selectedMultiVar
234
- });
265
+ }));
235
266
  }
236
267
  case "add.varSet.var":
237
268
  {
@@ -265,11 +296,11 @@ function settingsReducer(settings, action) {
265
296
  return v;
266
297
  }
267
298
  });
268
- return _objectSpread(_objectSpread({}, settings), {}, {
299
+ return validateSettings(_objectSpread(_objectSpread({}, settings), {}, {
269
300
  vars: vars,
270
301
  selectedVar: selectedVar,
271
302
  selectedMultiVar: selectedMultiVar
272
- });
303
+ }));
273
304
  }
274
305
  }
275
306
  case "remove.varSet.var":
@@ -296,11 +327,11 @@ function settingsReducer(settings, action) {
296
327
  var _settings$selectedVar3;
297
328
  const selectedVar = ((_settings$selectedVar3 = settings.selectedVar) === null || _settings$selectedVar3 === void 0 ? void 0 : _settings$selectedVar3.name) === action.varSet.name ? null : settings.selectedVar;
298
329
  const selectedMultiVar = settings.selectedMultiVar.filter(v => v.name !== action.varSet.name);
299
- return _objectSpread(_objectSpread({}, settings), {}, {
330
+ return validateSettings(_objectSpread(_objectSpread({}, settings), {}, {
300
331
  vars: vars,
301
332
  selectedVar: selectedVar,
302
333
  selectedMultiVar: selectedMultiVar
303
- });
334
+ }));
304
335
  } else {
305
336
  var _settings$selectedVar4;
306
337
  // Update selected if varSet is selected
@@ -316,11 +347,11 @@ function settingsReducer(settings, action) {
316
347
  return v;
317
348
  }
318
349
  });
319
- return _objectSpread(_objectSpread({}, settings), {}, {
350
+ return validateSettings(_objectSpread(_objectSpread({}, settings), {}, {
320
351
  vars: vars,
321
352
  selectedVar: selectedVar,
322
353
  selectedMultiVar: selectedMultiVar
323
- });
354
+ }));
324
355
  }
325
356
  }
326
357
  }
@@ -54,7 +54,8 @@ class MapHelper {
54
54
  return {
55
55
  longitude,
56
56
  latitude,
57
- zoom
57
+ zoom,
58
+ bounds
58
59
  };
59
60
  }
60
61
  }
package/dist/cjs/index.js CHANGED
@@ -39,24 +39,6 @@ Object.defineProperty(exports, "FullPage", {
39
39
  return _FullPage.FullPage;
40
40
  }
41
41
  });
42
- Object.defineProperty(exports, "FullPagePlots", {
43
- enumerable: true,
44
- get: function () {
45
- return _FullPage.FullPagePlots;
46
- }
47
- });
48
- Object.defineProperty(exports, "FullPagePseudospatial", {
49
- enumerable: true,
50
- get: function () {
51
- return _FullPagePseudospatial.FullPagePseudospatial;
52
- }
53
- });
54
- Object.defineProperty(exports, "FullPageScatterplot", {
55
- enumerable: true,
56
- get: function () {
57
- return _FullPage.FullPageScatterplot;
58
- }
59
- });
60
42
  Object.defineProperty(exports, "Heatmap", {
61
43
  enumerable: true,
62
44
  get: function () {
@@ -117,6 +99,12 @@ Object.defineProperty(exports, "OffcanvasVars", {
117
99
  return _offcanvas.OffcanvasVars;
118
100
  }
119
101
  });
102
+ Object.defineProperty(exports, "PLOT_TYPES", {
103
+ enumerable: true,
104
+ get: function () {
105
+ return _constants.PLOT_TYPES;
106
+ }
107
+ });
120
108
  Object.defineProperty(exports, "Pseudospatial", {
121
109
  enumerable: true,
122
110
  get: function () {
@@ -147,6 +135,12 @@ Object.defineProperty(exports, "SearchBar", {
147
135
  return _SearchBar.SearchBar;
148
136
  }
149
137
  });
138
+ Object.defineProperty(exports, "Toolbar", {
139
+ enumerable: true,
140
+ get: function () {
141
+ return _Toolbar.Toolbar;
142
+ }
143
+ });
150
144
  Object.defineProperty(exports, "VIOLIN_MODES", {
151
145
  enumerable: true,
152
146
  get: function () {
@@ -173,22 +167,22 @@ Object.defineProperty(exports, "ViolinControls", {
173
167
  });
174
168
  var _Dotplot = require("./components/dotplot/Dotplot");
175
169
  var _DotplotControls = require("./components/dotplot/DotplotControls");
170
+ var _FullPage = require("./components/full-page/FullPage");
176
171
  var _Heatmap = require("./components/heatmap/Heatmap");
177
172
  var _HeatmapControls = require("./components/heatmap/HeatmapControls");
178
173
  var _Matrixplot = require("./components/matrixplot/Matrixplot");
179
174
  var _MatrixplotControls = require("./components/matrixplot/MatrixplotControls");
180
175
  var _ObsList = require("./components/obs-list/ObsList");
181
176
  var _ObsmList = require("./components/obsm-list/ObsmList");
177
+ var _offcanvas = require("./components/offcanvas");
182
178
  var _Pseudospatial = require("./components/pseudospatial/Pseudospatial");
183
179
  var _Scatterplot = require("./components/scatterplot/Scatterplot");
184
180
  var _ScatterplotControls = require("./components/scatterplot/ScatterplotControls");
185
181
  var _SearchBar = require("./components/search-bar/SearchBar");
182
+ var _Toolbar = require("./components/toolbar/Toolbar");
186
183
  var _VarList = require("./components/var-list/VarList");
187
184
  var _Violin = require("./components/violin/Violin");
188
185
  var _ViolinControls = require("./components/violin/ViolinControls");
189
- var _FullPage = require("./components/full-page/FullPage");
190
- var _FullPagePseudospatial = require("./components/full-page/FullPagePseudospatial");
191
- var _offcanvas = require("./components/offcanvas");
192
186
  var _colorscales = require("./constants/colorscales");
193
187
  var _constants = require("./constants/constants");
194
188
  var _DatasetContext = require("./context/DatasetContext");
@@ -7216,7 +7216,7 @@ textarea.form-control-lg {
7216
7216
  display: inline-block !important;
7217
7217
  }
7218
7218
 
7219
- .d-block, .cherita-app .cherita-navbar {
7219
+ .d-block, .cherita-app .cherita-navbar, .cherita-app-container .cherita-app-canvas .cherita-navbar {
7220
7220
  display: block !important;
7221
7221
  }
7222
7222
 
@@ -7778,7 +7778,7 @@ textarea.form-control-lg {
7778
7778
  order: 6 !important;
7779
7779
  }
7780
7780
 
7781
- .m-0 {
7781
+ .m-0, .cherita-app-container .cherita-app-canvas .cherita-navbar {
7782
7782
  margin: 0 !important;
7783
7783
  }
7784
7784
 
@@ -7811,7 +7811,7 @@ textarea.form-control-lg {
7811
7811
  margin-left: 0 !important;
7812
7812
  }
7813
7813
 
7814
- .mx-1 {
7814
+ .mx-1, .js-plotly-plot .plotly .modebar .modebar-group {
7815
7815
  margin-right: 0.25rem !important;
7816
7816
  margin-left: 0.25rem !important;
7817
7817
  }
@@ -7988,11 +7988,11 @@ textarea.form-control-lg {
7988
7988
  margin-left: auto !important;
7989
7989
  }
7990
7990
 
7991
- .p-0 {
7991
+ .p-0, .cherita-app-container {
7992
7992
  padding: 0 !important;
7993
7993
  }
7994
7994
 
7995
- .p-1 {
7995
+ .p-1, .cherita-app-container .cherita-app-canvas {
7996
7996
  padding: 0.25rem !important;
7997
7997
  }
7998
7998
 
@@ -8666,7 +8666,7 @@ textarea.form-control-lg {
8666
8666
  --bs-link-underline-opacity: 1;
8667
8667
  }
8668
8668
 
8669
- .bg-primary {
8669
+ .bg-primary, .js-plotly-plot .plotly .modebar .modebar-group {
8670
8670
  --bs-bg-opacity: 1;
8671
8671
  background-color: rgba(var(--bs-primary-rgb), var(--bs-bg-opacity)) !important;
8672
8672
  }
@@ -11927,6 +11927,7 @@ textarea.form-control-lg {
11927
11927
 
11928
11928
  .cherita-app {
11929
11929
  position: relative;
11930
+ width: 100%;
11930
11931
  }
11931
11932
 
11932
11933
  .cherita-app .cherita-navbar {
@@ -11961,6 +11962,18 @@ textarea.form-control-lg {
11961
11962
  .cherita-app-sidebar .card-body {
11962
11963
  overflow-y: hidden;
11963
11964
  }
11965
+ .cherita-app-sidebar .sidebar-plotselector {
11966
+ padding: 6px;
11967
+ border-bottom: 1px solid #dee2e6;
11968
+ }
11969
+ .cherita-app-sidebar .sidebar-plotselector .plotselector-icon {
11970
+ padding-bottom: 2px;
11971
+ cursor: pointer;
11972
+ }
11973
+ .cherita-app-sidebar .sidebar-plotselector .plotselector-icon .active {
11974
+ opacity: 1;
11975
+ border-bottom: 2px solid #007bff;
11976
+ }
11964
11977
  .cherita-app-sidebar .sidebar-pseudospatial {
11965
11978
  padding: 10px;
11966
11979
  border-bottom: 1px solid #dee2e6;
@@ -12011,36 +12024,77 @@ textarea.form-control-lg {
12011
12024
  border-left: 1px solid #dee2e6;
12012
12025
  }
12013
12026
 
12027
+ .cherita-app-canvas .cherita-plot {
12028
+ height: 100%;
12029
+ min-height: 400px;
12030
+ }
12031
+
12032
+ .cherita-app-container {
12033
+ display: flex;
12034
+ flex-wrap: nowrap;
12035
+ width: 100%;
12036
+ height: 100%;
12037
+ }
12038
+ .cherita-app-container .cherita-app-obs {
12039
+ flex: 0 0 auto;
12040
+ min-width: 350px;
12041
+ max-width: 20%;
12042
+ overflow-y: auto;
12043
+ }
12044
+ .cherita-app-container .cherita-app-canvas {
12045
+ flex: 1 1 auto;
12046
+ min-width: 400px;
12047
+ position: relative;
12048
+ max-height: 100%;
12049
+ display: flex;
12050
+ flex-direction: column;
12051
+ }
12052
+ .cherita-app-container .cherita-app-canvas .cherita-navbar {
12053
+ position: relative;
12054
+ }
12055
+ .cherita-app-container .cherita-app-sidebar {
12056
+ flex: 0 0 auto;
12057
+ min-width: 350px;
12058
+ max-width: 20%;
12059
+ position: relative;
12060
+ }
12061
+ @media (max-width: 1400px) {
12062
+ .cherita-app-container .cherita-app-obs,
12063
+ .cherita-app-container .cherita-app-sidebar {
12064
+ max-width: 25%;
12065
+ }
12066
+ }
12067
+
12014
12068
  .ps-xs-1 {
12015
12069
  padding-left: 0.15rem !important;
12016
12070
  }
12017
12071
 
12018
- .js-plotly-plot .plotly .modebar {
12019
- border-radius: 5px;
12020
- background-color: rgba(0, 0, 0, 0.6);
12021
- padding: 0 4px !important;
12022
- }
12023
12072
  .js-plotly-plot .plotly .modebar .modebar-group {
12024
- margin: 0 !important;
12025
- padding: 0 !important;
12026
- background-color: transparent !important;
12073
+ border-radius: 5px;
12074
+ padding: 4px !important;
12027
12075
  }
12028
12076
  .js-plotly-plot .plotly .modebar .modebar-group .modebar-btn {
12029
- fill: white !important; /* Ensures white icons */
12030
- color: white !important; /* Ensures text/icons are visible */
12077
+ display: inline-flex;
12078
+ justify-content: center;
12031
12079
  position: relative;
12032
- font-size: 16px;
12033
- padding: 4px;
12080
+ font-size: 1.25rem;
12081
+ padding: 0.25rem;
12034
12082
  height: auto;
12035
12083
  cursor: pointer;
12036
12084
  line-height: normal;
12037
12085
  }
12038
12086
  .js-plotly-plot .plotly .modebar .modebar-group .modebar-btn svg {
12039
12087
  position: relative;
12040
- top: auto;
12041
- bottom: auto;
12042
- left: auto;
12043
- right: auto;
12088
+ top: 1px;
12089
+ }
12090
+ .js-plotly-plot .plotly .modebar .modebar-group .modebar-btn svg path {
12091
+ fill: white !important;
12092
+ color: white !important;
12093
+ }
12094
+
12095
+ .js-plotly-plot .plotly .modebar--hover > :not(.watermark) {
12096
+ opacity: 0.5;
12097
+ transition: opacity 0.3s;
12044
12098
  }
12045
12099
 
12046
12100
  .cherita-spatial-controls {
@@ -12118,7 +12172,6 @@ textarea.form-control-lg {
12118
12172
 
12119
12173
  /* End scrollbar styling */
12120
12174
  .cherita-container-plot {
12121
- margin-top: 76px;
12122
12175
  padding: 20px;
12123
12176
  position: relative;
12124
12177
  min-height: 400px;