@haniffalab/cherita-react 1.4.1 → 1.4.2

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 +100 -74
  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 +258 -210
  20. package/dist/cjs/components/obs-list/ObsList.js +161 -133
  21. package/dist/cjs/components/obs-list/ObsToolbar.js +2 -3
  22. package/dist/cjs/components/obsm-list/ObsmList.js +53 -38
  23. package/dist/cjs/components/offcanvas/index.js +61 -31
  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 +127 -99
  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 +168 -121
  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 +115 -88
  35. package/dist/cjs/components/var-list/VarList.js +85 -69
  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 -107
  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 +47 -47
  42. package/dist/cjs/context/DatasetContext.js +24 -16
  43. package/dist/cjs/context/FilterContext.js +11 -9
  44. package/dist/cjs/context/SettingsContext.js +255 -89
  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 +34 -27
  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 +64 -42
  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 +120 -93
  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 +273 -222
  82. package/dist/esm/components/obs-list/ObsList.js +176 -147
  83. package/dist/esm/components/obs-list/ObsToolbar.js +3 -3
  84. package/dist/esm/components/obsm-list/ObsmList.js +60 -44
  85. package/dist/esm/components/offcanvas/index.js +67 -37
  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 +148 -119
  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 +180 -132
  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 +126 -98
  97. package/dist/esm/components/var-list/VarList.js +99 -82
  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 -118
  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 +47 -47
  104. package/dist/esm/context/DatasetContext.js +31 -22
  105. package/dist/esm/context/FilterContext.js +11 -8
  106. package/dist/esm/context/SettingsContext.js +257 -90
  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 +35 -27
  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 +18 -7
  127. package/scss/cherita-bootstrap.scss +2 -2
  128. package/scss/cherita.scss +43 -17
  129. package/scss/components/accordions.scss +4 -1
  130. package/scss/components/layouts.scss +15 -33
  131. package/scss/components/lists.scss +8 -4
  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
package/README.md CHANGED
@@ -21,7 +21,7 @@ Install packages
21
21
  npm i
22
22
  ```
23
23
 
24
- Create a ``.env`` file within ``sites/demo`` to store environment variables for Vite to use. Within it set ``REACT_APP_API_URL`` to the backend API url like
24
+ Create a `.env` file within `sites/demo` to store environment variables for Vite to use. Within it set `REACT_APP_API_URL` to the backend API url like
25
25
 
26
26
  ```sh
27
27
  REACT_APP_API_URL=http://localhost:5000/api/
@@ -4,30 +4,34 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.ScaleSelect = exports.ColorscaleSelect = void 0;
7
- var _react = _interopRequireDefault(require("react"));
8
7
  var _lodash = _interopRequireDefault(require("lodash"));
9
8
  var _reactBootstrap = require("react-bootstrap");
10
9
  var _colorscales = require("../../constants/colorscales");
11
10
  var _constants = require("../../constants/constants");
12
11
  var _SettingsContext = require("../../context/SettingsContext");
12
+ var _jsxRuntime = require("react/jsx-runtime");
13
13
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
14
14
  const ColorscaleSelect = () => {
15
15
  const settings = (0, _SettingsContext.useSettings)();
16
16
  const dispatch = (0, _SettingsContext.useSettingsDispatch)();
17
- return /*#__PURE__*/_react.default.createElement(_reactBootstrap.Form.Group, {
18
- className: "mb-2"
19
- }, /*#__PURE__*/_react.default.createElement(_reactBootstrap.Form.Label, null, "Colorscale"), /*#__PURE__*/_react.default.createElement(_reactBootstrap.Form.Select, {
20
- value: settings.controls.colorScale,
21
- onChange: e => {
22
- dispatch({
23
- type: "set.controls.colorScale",
24
- colorScale: e.target.value
25
- });
26
- }
27
- }, _lodash.default.keys(_colorscales.COLORSCALES).map(key => /*#__PURE__*/_react.default.createElement("option", {
28
- key: key,
29
- value: key
30
- }, key))));
17
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactBootstrap.Form.Group, {
18
+ className: "mb-2",
19
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Form.Label, {
20
+ children: "Colorscale"
21
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Form.Select, {
22
+ value: settings.controls.colorScale,
23
+ onChange: e => {
24
+ dispatch({
25
+ type: 'set.controls.colorScale',
26
+ colorScale: e.target.value
27
+ });
28
+ },
29
+ children: _lodash.default.keys(_colorscales.COLORSCALES).map(key => /*#__PURE__*/(0, _jsxRuntime.jsx)("option", {
30
+ value: key,
31
+ children: key
32
+ }, key))
33
+ })]
34
+ });
31
35
  };
32
36
  exports.ColorscaleSelect = ColorscaleSelect;
33
37
  const ScaleSelect = _ref => {
@@ -41,20 +45,24 @@ const ScaleSelect = _ref => {
41
45
  matrixplot: _constants.MATRIXPLOT_SCALES,
42
46
  violinplot: _constants.VIOLINPLOT_SCALES
43
47
  };
44
- return /*#__PURE__*/_react.default.createElement(_reactBootstrap.Form.Group, {
45
- className: "mb-2"
46
- }, /*#__PURE__*/_react.default.createElement(_reactBootstrap.Form.Label, null, "Standard scale"), /*#__PURE__*/_react.default.createElement(_reactBootstrap.Form.Select, {
47
- value: settings.controls.scale[plot] || "",
48
- onChange: e => {
49
- dispatch({
50
- type: "set.controls.scale",
51
- plot: plot,
52
- scale: !e.target.value.length ? null : e.target.value
53
- });
54
- }
55
- }, _lodash.default.values(SCALES[plot]).map(scale => /*#__PURE__*/_react.default.createElement("option", {
56
- key: scale.value,
57
- value: scale.value || ""
58
- }, scale.name))));
48
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactBootstrap.Form.Group, {
49
+ className: "mb-2",
50
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Form.Label, {
51
+ children: "Standard scale"
52
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Form.Select, {
53
+ value: settings.controls.scale[plot] || '',
54
+ onChange: e => {
55
+ dispatch({
56
+ type: 'set.controls.scale',
57
+ plot: plot,
58
+ scale: !e.target.value.length ? null : e.target.value
59
+ });
60
+ },
61
+ children: _lodash.default.values(SCALES[plot]).map(scale => /*#__PURE__*/(0, _jsxRuntime.jsx)("option", {
62
+ value: scale.value || '',
63
+ children: scale.name
64
+ }, scale.value))
65
+ })]
66
+ });
59
67
  };
60
68
  exports.ScaleSelect = ScaleSelect;
@@ -4,7 +4,7 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.Dotplot = Dotplot;
7
- var _react = _interopRequireWildcard(require("react"));
7
+ var _react = require("react");
8
8
  var _lodash = _interopRequireDefault(require("lodash"));
9
9
  var _reactBootstrap = require("react-bootstrap");
10
10
  var _reactPlotly = _interopRequireDefault(require("react-plotly.js"));
@@ -14,25 +14,28 @@ var _FilterContext = require("../../context/FilterContext");
14
14
  var _SettingsContext = require("../../context/SettingsContext");
15
15
  var _LoadingIndicators = require("../../utils/LoadingIndicators");
16
16
  var _requests = require("../../utils/requests");
17
+ var _Resolver = require("../../utils/Resolver");
18
+ var _PlotAlert = require("../full-page/PlotAlert");
17
19
  var _Toolbar = require("../toolbar/Toolbar");
20
+ var _jsxRuntime = require("react/jsx-runtime");
18
21
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
19
- function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
20
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; }
21
23
  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; }
22
24
  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; }
23
25
  function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
24
26
  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); }
25
27
  function Dotplot(_ref) {
26
- var _settings$selectedObs, _settings$selectedObs2, _settings$selectedObs3;
27
28
  let {
28
29
  showObsBtn = false,
29
30
  showVarsBtn = false,
30
31
  showCtrlsBtn = false,
31
32
  setShowObs,
32
33
  setShowVars,
33
- setShowControls
34
+ setShowControls,
35
+ plotType,
36
+ setPlotType
34
37
  } = _ref;
35
- const ENDPOINT = "dotplot";
38
+ const ENDPOINT = 'dotplot';
36
39
  const dataset = (0, _DatasetContext.useDataset)();
37
40
  const settings = (0, _SettingsContext.useSettings)();
38
41
  const {
@@ -44,14 +47,13 @@ function Dotplot(_ref) {
44
47
  const [data, setData] = (0, _react.useState)([]);
45
48
  const [layout, setLayout] = (0, _react.useState)({});
46
49
  const [hasSelections, setHasSelections] = (0, _react.useState)(false);
47
- const [params, setParams] = (0, _react.useState)({
50
+ const selectedObs = (0, _Resolver.useSelectedObs)();
51
+ const selectedMultiVar = (0, _Resolver.useSelectedMultiVar)();
52
+ const params = (0, _react.useMemo)(() => ({
48
53
  url: dataset.url,
49
- obsCol: settings.selectedObs,
50
- obsValues: !((_settings$selectedObs = settings.selectedObs) !== null && _settings$selectedObs !== void 0 && _settings$selectedObs.omit.length) ? null : _lodash.default.difference(_lodash.default.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 => {
51
- var _settings$selectedObs4;
52
- return (_settings$selectedObs4 = settings.selectedObs) === null || _settings$selectedObs4 === void 0 ? void 0 : _settings$selectedObs4.codesMap[c];
53
- }),
54
- varKeys: settings.selectedMultiVar.map(i => i.isSet ? {
54
+ obsCol: selectedObs,
55
+ obsValues: !(selectedObs !== null && selectedObs !== void 0 && selectedObs.omit.length) ? null : _lodash.default.difference(selectedObs === null || selectedObs === void 0 ? void 0 : selectedObs.values, selectedObs === null || selectedObs === void 0 ? void 0 : selectedObs.omit),
56
+ varKeys: selectedMultiVar.map(i => i.isSet ? {
55
57
  name: i.name,
56
58
  indices: i.vars.map(v => v.index)
57
59
  } : i.index),
@@ -60,36 +62,16 @@ function Dotplot(_ref) {
60
62
  meanOnlyExpressed: settings.controls.meanOnlyExpressed,
61
63
  expressionCutoff: settings.controls.expressionCutoff,
62
64
  varNamesCol: dataset.varNamesCol
63
- });
65
+ }), [dataset.url, dataset.varNamesCol, isSliced, obsIndices, selectedMultiVar, selectedObs, settings.controls.expressionCutoff, settings.controls.meanOnlyExpressed, settings.controls.scale.dotplot]);
64
66
  // @TODO: set default scale
65
67
 
66
68
  (0, _react.useEffect)(() => {
67
- if (settings.selectedObs && settings.selectedMultiVar.length) {
69
+ if (selectedObs && selectedMultiVar.length) {
68
70
  setHasSelections(true);
69
71
  } else {
70
72
  setHasSelections(false);
71
73
  }
72
- setParams(p => {
73
- var _settings$selectedObs5, _settings$selectedObs6, _settings$selectedObs7;
74
- return _objectSpread(_objectSpread({}, p), {}, {
75
- url: dataset.url,
76
- obsCol: settings.selectedObs,
77
- obsValues: !((_settings$selectedObs5 = settings.selectedObs) !== null && _settings$selectedObs5 !== void 0 && _settings$selectedObs5.omit.length) ? null : _lodash.default.difference(_lodash.default.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 => {
78
- var _settings$selectedObs8;
79
- return (_settings$selectedObs8 = settings.selectedObs) === null || _settings$selectedObs8 === void 0 ? void 0 : _settings$selectedObs8.codesMap[c];
80
- }),
81
- varKeys: settings.selectedMultiVar.map(i => i.isSet ? {
82
- name: i.name,
83
- indices: i.vars.map(v => v.index)
84
- } : i.index),
85
- obsIndices: isSliced ? [...(obsIndices || [])] : null,
86
- standardScale: settings.controls.scale.dotplot,
87
- meanOnlyExpressed: settings.controls.meanOnlyExpressed,
88
- expressionCutoff: settings.controls.expressionCutoff,
89
- varNamesCol: dataset.varNamesCol
90
- });
91
- });
92
- }, [dataset.url, settings.selectedObs, settings.selectedMultiVar, settings.controls.scale.dotplot, settings.controls.meanOnlyExpressed, settings.controls.expressionCutoff, dataset.varNamesCol, isSliced, obsIndices]);
74
+ }, [dataset.url, selectedObs, settings.controls.scale.dotplot, settings.controls.meanOnlyExpressed, settings.controls.expressionCutoff, dataset.varNamesCol, isSliced, obsIndices, selectedMultiVar]);
93
75
  const updateColorscale = (0, _react.useCallback)(colorscale => {
94
76
  setLayout(l => {
95
77
  return _objectSpread(_objectSpread({}, l), {}, {
@@ -104,14 +86,15 @@ function Dotplot(_ref) {
104
86
  isPending,
105
87
  serverError
106
88
  } = (0, _requests.useDebouncedFetch)(ENDPOINT, params, 500, {
107
- enabled: !!params.obsCol && !!params.varKeys.length
89
+ isEnabled: params => !!params.obsCol && !!params.varKeys.length
108
90
  });
109
91
  (0, _react.useEffect)(() => {
110
- if (hasSelections && !isPending && !serverError) {
92
+ if (hasSelections && !!fetchedData && !isPending && !serverError) {
111
93
  setData(fetchedData.data);
112
94
  setLayout(fetchedData.layout);
95
+ // @TODO: keep colorAxis range from settings
113
96
  dispatch({
114
- type: "set.controls.colorAxis",
97
+ type: 'set.controls.colorAxis',
115
98
  colorAxis: {
116
99
  dmin: fetchedData.range.min.toFixed(1),
117
100
  dmax: fetchedData.range.max.toFixed(1),
@@ -120,6 +103,9 @@ function Dotplot(_ref) {
120
103
  }
121
104
  });
122
105
  updateColorscale(colorscale.current);
106
+ } else {
107
+ setData([]);
108
+ setLayout({});
123
109
  }
124
110
  }, [fetchedData, isPending, serverError, hasSelections, dispatch, updateColorscale]);
125
111
  (0, _react.useEffect)(() => {
@@ -146,38 +132,50 @@ function Dotplot(_ref) {
146
132
  const modeBarButtons = customModeBarButtons.length ? [customModeBarButtons, _constants.PLOTLY_MODEBAR_BUTTONS] : [_constants.PLOTLY_MODEBAR_BUTTONS];
147
133
  if (!serverError) {
148
134
  if (hasSelections) {
149
- return /*#__PURE__*/_react.default.createElement("div", {
150
- className: "cherita-plot cherita-dotplot position-relative"
151
- }, isPending && /*#__PURE__*/_react.default.createElement(_LoadingIndicators.LoadingSpinner, null), /*#__PURE__*/_react.default.createElement(_reactPlotly.default, {
152
- data: data,
153
- layout: layout,
154
- useResizeHandler: true,
155
- style: {
156
- width: "100%",
157
- height: "100%"
158
- },
159
- config: {
160
- displaylogo: false,
161
- modeBarButtons: modeBarButtons
162
- }
163
- }));
135
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
136
+ className: "cherita-plot cherita-dotplot position-relative",
137
+ children: [isPending && /*#__PURE__*/(0, _jsxRuntime.jsx)(_LoadingIndicators.LoadingSpinner, {}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactPlotly.default, {
138
+ data: data,
139
+ layout: layout,
140
+ useResizeHandler: true,
141
+ style: {
142
+ width: '100%',
143
+ height: '100%'
144
+ },
145
+ config: {
146
+ displaylogo: false,
147
+ modeBarButtons: modeBarButtons
148
+ }
149
+ })]
150
+ });
164
151
  }
165
- return /*#__PURE__*/_react.default.createElement("div", {
166
- className: "cherita-dotplot"
167
- }, /*#__PURE__*/_react.default.createElement(_reactBootstrap.Alert, {
168
- variant: "light"
169
- }, "Select", " ", showVarsBtn ? /*#__PURE__*/_react.default.createElement(_reactBootstrap.Button, {
170
- variant: "link",
171
- className: "border-0 p-0 align-baseline",
172
- onClick: setShowVars
173
- }, "features") : "features", " ", "and a", " ", showObsBtn ? /*#__PURE__*/_react.default.createElement(_reactBootstrap.Button, {
174
- variant: "link",
175
- className: "border-0 p-0 align-baseline",
176
- onClick: setShowObs
177
- }, "category") : "category"));
152
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_PlotAlert.PlotAlert, {
153
+ variant: "info",
154
+ heading: "Set up your dotplot",
155
+ plotType: plotType,
156
+ setPlotType: setPlotType,
157
+ children: /*#__PURE__*/(0, _jsxRuntime.jsxs)("p", {
158
+ className: "p-0 m-0",
159
+ children: ["Select one or more", ' ', showVarsBtn ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Button, {
160
+ variant: "link",
161
+ className: "border-0 p-0 align-baseline",
162
+ onClick: setShowVars,
163
+ children: "features"
164
+ }) : 'features', ' ', "to display their expression across groups, then choose a", ' ', showObsBtn ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Button, {
165
+ variant: "link",
166
+ className: "border-0 p-0 align-baseline",
167
+ onClick: setShowObs,
168
+ children: "category"
169
+ }) : 'category', ' ', "to group observations in the dotplot."]
170
+ })
171
+ });
178
172
  } else {
179
- return /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement(_reactBootstrap.Alert, {
180
- variant: "danger"
181
- }, serverError.message));
173
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_PlotAlert.PlotAlert, {
174
+ variant: "danger",
175
+ heading: "Error displaying the dotplot",
176
+ plotType: plotType,
177
+ setPlotType: setPlotType,
178
+ children: serverError.message || 'An unexpected error occurred while generating the plot.'
179
+ });
182
180
  }
183
181
  }
@@ -4,11 +4,11 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.DotplotControls = DotplotControls;
7
- var _react = _interopRequireWildcard(require("react"));
7
+ var _react = require("react");
8
8
  var _reactBootstrap = require("react-bootstrap");
9
9
  var _SettingsContext = require("../../context/SettingsContext");
10
10
  var _Controls = require("../controls/Controls");
11
- 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); }
11
+ var _jsxRuntime = require("react/jsx-runtime");
12
12
  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; }
13
13
  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; }
14
14
  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,88 +33,108 @@ function DotplotControls() {
33
33
  expressionCutoff: settings.controls.expressionCutoff
34
34
  }));
35
35
  }, [settings.controls.colorAxis.cmin, settings.controls.colorAxis.cmax, settings.controls.expressionCutoff]);
36
- return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_reactBootstrap.Form, null, /*#__PURE__*/_react.default.createElement(_Controls.ColorscaleSelect, null), /*#__PURE__*/_react.default.createElement(_reactBootstrap.Form.Group, {
37
- className: "mb-2"
38
- }, /*#__PURE__*/_react.default.createElement(_reactBootstrap.InputGroup, null, /*#__PURE__*/_react.default.createElement(_reactBootstrap.InputGroup.Text, null, "min"), /*#__PURE__*/_react.default.createElement(_reactBootstrap.Form.Control, {
39
- name: "scaleMin",
40
- size: "sm",
41
- type: "number",
42
- value: controls.colorAxis.cmin,
43
- step: 0.1,
44
- min: Math.min(settings.controls.colorAxis.dmin, 0.0),
45
- max: settings.controls.colorAxis.dmax,
46
- onChange: e => {
47
- setControls(_objectSpread(_objectSpread({}, controls), {}, {
48
- colorAxis: _objectSpread(_objectSpread({}, controls.colorAxis), {}, {
49
- cmin: e.target.value
36
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_jsxRuntime.Fragment, {
37
+ children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactBootstrap.Form, {
38
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_Controls.ColorscaleSelect, {}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Form.Group, {
39
+ className: "mb-2",
40
+ children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactBootstrap.InputGroup, {
41
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.InputGroup.Text, {
42
+ children: "min"
43
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Form.Control, {
44
+ name: "scaleMin",
45
+ size: "sm",
46
+ type: "number",
47
+ value: controls.colorAxis.cmin,
48
+ step: 0.1,
49
+ min: Math.min(settings.controls.colorAxis.dmin, 0.0),
50
+ max: settings.controls.colorAxis.dmax,
51
+ onChange: e => {
52
+ setControls(_objectSpread(_objectSpread({}, controls), {}, {
53
+ colorAxis: _objectSpread(_objectSpread({}, controls.colorAxis), {}, {
54
+ cmin: e.target.value
55
+ })
56
+ }));
57
+ }
58
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.InputGroup.Text, {
59
+ children: "max"
60
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Form.Control, {
61
+ name: "scaleMax",
62
+ size: "sm",
63
+ type: "number",
64
+ value: controls.colorAxis.cmax,
65
+ step: 0.1,
66
+ min: controls.colorAxis.cmin,
67
+ max: settings.controls.colorAxis.dmax,
68
+ onChange: e => {
69
+ if (parseFloat(e.target.value) > settings.controls.colorAxis.dmax) {
70
+ e.target.value = settings.controls.colorAxis.dmax.toFixed(1);
71
+ }
72
+ setControls(_objectSpread(_objectSpread({}, controls), {}, {
73
+ colorAxis: _objectSpread(_objectSpread({}, controls.colorAxis), {}, {
74
+ cmax: e.target.value
75
+ })
76
+ }));
77
+ }
78
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Button, {
79
+ variant: "outline-primary",
80
+ onClick: () => dispatch({
81
+ type: 'set.controls.colorAxis.crange',
82
+ cmin: controls.colorAxis.cmin,
83
+ cmax: controls.colorAxis.cmax
84
+ }),
85
+ children: "Apply"
86
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Button, {
87
+ variant: "outline-primary",
88
+ onClick: () => dispatch({
89
+ type: 'set.controls.colorAxis.crange',
90
+ cmin: settings.controls.colorAxis.dmin,
91
+ cmax: settings.controls.colorAxis.dmax
92
+ }),
93
+ children: "Reset"
94
+ })]
50
95
  })
51
- }));
52
- }
53
- }), /*#__PURE__*/_react.default.createElement(_reactBootstrap.InputGroup.Text, null, "max"), /*#__PURE__*/_react.default.createElement(_reactBootstrap.Form.Control, {
54
- name: "scaleMax",
55
- size: "sm",
56
- type: "number",
57
- value: controls.colorAxis.cmax,
58
- step: 0.1,
59
- min: controls.colorAxis.cmin,
60
- max: settings.controls.colorAxis.dmax,
61
- onChange: e => {
62
- if (parseFloat(e.target.value) > settings.controls.colorAxis.dmax) {
63
- e.target.value = settings.controls.colorAxis.dmax.toFixed(1);
64
- }
65
- setControls(_objectSpread(_objectSpread({}, controls), {}, {
66
- colorAxis: _objectSpread(_objectSpread({}, controls.colorAxis), {}, {
67
- cmax: e.target.value
96
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_Controls.ScaleSelect, {
97
+ plot: "dotplot"
98
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactBootstrap.Form.Group, {
99
+ className: "mb-2",
100
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Form.Label, {
101
+ children: "Expression Cutoff"
102
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactBootstrap.InputGroup, {
103
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Form.Control, {
104
+ size: "sm",
105
+ type: "number",
106
+ step: '0.1',
107
+ min: 0.0,
108
+ value: controls.expressionCutoff,
109
+ onChange: e => {
110
+ setControls(_objectSpread(_objectSpread({}, controls), {}, {
111
+ expressionCutoff: e.target.value
112
+ }));
113
+ }
114
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Button, {
115
+ variant: "outline-primary",
116
+ onClick: () => dispatch({
117
+ type: 'set.controls.expressionCutoff',
118
+ expressionCutoff: parseFloat(controls.expressionCutoff)
119
+ }),
120
+ children: "Apply"
121
+ })]
122
+ })]
123
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Form.Group, {
124
+ className: "mb-2",
125
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Form.Check, {
126
+ type: "switch",
127
+ id: "meanOnlyExpressed",
128
+ label: "Average only above cutoff",
129
+ checked: settings.controls.meanOnlyExpressed,
130
+ onChange: () => {
131
+ dispatch({
132
+ type: 'set.controls.meanOnlyExpressed',
133
+ meanOnlyExpressed: !settings.controls.meanOnlyExpressed
134
+ });
135
+ }
68
136
  })
69
- }));
70
- }
71
- }), /*#__PURE__*/_react.default.createElement(_reactBootstrap.Button, {
72
- variant: "outline-primary",
73
- onClick: () => dispatch({
74
- type: "set.controls.colorAxis.crange",
75
- cmin: controls.colorAxis.cmin,
76
- cmax: controls.colorAxis.cmax
137
+ })]
77
138
  })
78
- }, "Apply"), /*#__PURE__*/_react.default.createElement(_reactBootstrap.Button, {
79
- variant: "outline-primary",
80
- onClick: () => dispatch({
81
- type: "set.controls.colorAxis.crange",
82
- cmin: settings.controls.colorAxis.dmin,
83
- cmax: settings.controls.colorAxis.dmax
84
- })
85
- }, "Reset"))), /*#__PURE__*/_react.default.createElement(_Controls.ScaleSelect, {
86
- plot: "dotplot"
87
- }), /*#__PURE__*/_react.default.createElement(_reactBootstrap.Form.Group, {
88
- className: "mb-2"
89
- }, /*#__PURE__*/_react.default.createElement(_reactBootstrap.Form.Label, null, "Expression Cutoff"), /*#__PURE__*/_react.default.createElement(_reactBootstrap.InputGroup, null, /*#__PURE__*/_react.default.createElement(_reactBootstrap.Form.Control, {
90
- size: "sm",
91
- type: "number",
92
- step: "0.1",
93
- min: 0.0,
94
- value: controls.expressionCutoff,
95
- onChange: e => {
96
- setControls(_objectSpread(_objectSpread({}, controls), {}, {
97
- expressionCutoff: e.target.value
98
- }));
99
- }
100
- }), /*#__PURE__*/_react.default.createElement(_reactBootstrap.Button, {
101
- variant: "outline-primary",
102
- onClick: () => dispatch({
103
- type: "set.controls.expressionCutoff",
104
- expressionCutoff: parseFloat(controls.expressionCutoff)
105
- })
106
- }, "Apply"))), /*#__PURE__*/_react.default.createElement(_reactBootstrap.Form.Group, {
107
- className: "mb-2"
108
- }, /*#__PURE__*/_react.default.createElement(_reactBootstrap.Form.Check, {
109
- type: "switch",
110
- id: "meanOnlyExpressed",
111
- label: "Average only above cutoff",
112
- checked: settings.controls.meanOnlyExpressed,
113
- onChange: () => {
114
- dispatch({
115
- type: "set.controls.meanOnlyExpressed",
116
- meanOnlyExpressed: !settings.controls.meanOnlyExpressed
117
- });
118
- }
119
- }))));
139
+ });
120
140
  }