@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
@@ -1,32 +1,36 @@
1
- const _excluded = ["isPseudospatial", "searchDiseases", "defaultPlotType"];
2
- 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); }
1
+ const _excluded = ["searchDiseases", "defaultPlotType"];
2
+ 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; }
3
+ 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; }
4
+ 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; }
5
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
6
+ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
3
7
  function _objectWithoutProperties(e, t) { if (null == e) return {}; var o, r, i = _objectWithoutPropertiesLoose(e, t); if (Object.getOwnPropertySymbols) { var n = Object.getOwnPropertySymbols(e); for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]); } return i; }
4
8
  function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
5
- import React, { useEffect, useMemo, useState } from "react";
6
- import { useMediaQuery } from "@mui/material";
7
- import { Card, Container, Modal } from "react-bootstrap";
8
- import { BREAKPOINTS, PLOT_TYPES, SELECTION_MODES, VIOLIN_MODES } from "../../constants/constants";
9
- import { DatasetProvider } from "../../context/DatasetContext";
10
- import { Dotplot } from "../dotplot/Dotplot";
11
- import { DotplotControls } from "../dotplot/DotplotControls";
12
- import { PlotTypeSelector } from "../full-page/PlotTypeSelector";
13
- import { Heatmap } from "../heatmap/Heatmap";
14
- import { HeatmapControls } from "../heatmap/HeatmapControls";
15
- import { Matrixplot } from "../matrixplot/Matrixplot";
16
- import { MatrixplotControls } from "../matrixplot/MatrixplotControls";
17
- import { ObsColsList } from "../obs-list/ObsList";
18
- import { OffcanvasControls, OffcanvasObs, OffcanvasObsm, OffcanvasVars } from "../offcanvas";
19
- import { Pseudospatial } from "../pseudospatial/Pseudospatial";
20
- import { PseudospatialToolbar } from "../pseudospatial/PseudospatialToolbar";
21
- import { Scatterplot } from "../scatterplot/Scatterplot";
22
- import { ScatterplotControls } from "../scatterplot/ScatterplotControls";
23
- import { SearchBar } from "../search-bar/SearchBar";
24
- import { VarNamesList } from "../var-list/VarList";
25
- import { Violin } from "../violin/Violin";
26
- import { ViolinControls } from "../violin/ViolinControls";
9
+ import { useEffect, useMemo, useState } from 'react';
10
+ import { useMediaQuery } from '@mui/material';
11
+ import { Card, Container, Modal } from 'react-bootstrap';
12
+ import { BREAKPOINTS, PLOT_TYPES, SELECTION_MODES, VIOLIN_MODES } from '../../constants/constants';
13
+ import { DatasetProvider } from '../../context/DatasetContext';
14
+ import { Dotplot } from '../dotplot/Dotplot';
15
+ import { DotplotControls } from '../dotplot/DotplotControls';
16
+ import { Heatmap } from '../heatmap/Heatmap';
17
+ import { HeatmapControls } from '../heatmap/HeatmapControls';
18
+ import { Matrixplot } from '../matrixplot/Matrixplot';
19
+ import { MatrixplotControls } from '../matrixplot/MatrixplotControls';
20
+ import { ObsColsList } from '../obs-list/ObsList';
21
+ import { OffcanvasControls, OffcanvasObs, OffcanvasObsm, OffcanvasVars } from '../offcanvas';
22
+ import { PlotTypeSelector } from './PlotTypeSelector';
23
+ import { Pseudospatial } from '../pseudospatial/Pseudospatial';
24
+ import { PseudospatialToolbar } from '../pseudospatial/PseudospatialToolbar';
25
+ import { Scatterplot } from '../scatterplot/Scatterplot';
26
+ import { ScatterplotControls } from '../scatterplot/ScatterplotControls';
27
+ import { SearchBar } from '../search-bar/SearchBar';
28
+ import { VarNamesList } from '../var-list/VarList';
29
+ import { Violin } from '../violin/Violin';
30
+ import { ViolinControls } from '../violin/ViolinControls';
31
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
27
32
  export function FullPage(_ref) {
28
33
  let {
29
- isPseudospatial = false,
30
34
  searchDiseases = true,
31
35
  defaultPlotType = PLOT_TYPES.SCATTERPLOT
32
36
  } = _ref,
@@ -39,6 +43,9 @@ export function FullPage(_ref) {
39
43
  const [plotType, setPlotType] = useState(defaultPlotType || PLOT_TYPES.SCATTERPLOT);
40
44
  const [showPseudospatialControls, setShowPseudospatialControls] = useState(false);
41
45
  const [pseudospatialPlotType, setpseudospatialPlotType] = useState(null);
46
+ const {
47
+ isPseudospatial = false
48
+ } = props;
42
49
  useEffect(() => {
43
50
  setPlotType(defaultPlotType || PLOT_TYPES.SCATTERPLOT);
44
51
  }, [defaultPlotType]);
@@ -82,88 +89,108 @@ export function FullPage(_ref) {
82
89
  showObsBtn,
83
90
  showVarsBtn,
84
91
  showCtrlsBtn: true,
92
+ plotType,
85
93
  setShowObs,
86
94
  setShowVars,
87
- setShowControls
95
+ setShowControls,
96
+ setPlotType
88
97
  };
89
98
  switch (plotType) {
90
99
  case PLOT_TYPES.DOTPLOT:
91
- return /*#__PURE__*/React.createElement(Dotplot, commonProps);
100
+ return /*#__PURE__*/_jsx(Dotplot, _objectSpread({}, commonProps));
92
101
  case PLOT_TYPES.MATRIXPLOT:
93
- return /*#__PURE__*/React.createElement(Matrixplot, commonProps);
102
+ return /*#__PURE__*/_jsx(Matrixplot, _objectSpread({}, commonProps));
94
103
  case PLOT_TYPES.HEATMAP:
95
- return /*#__PURE__*/React.createElement(Heatmap, commonProps);
104
+ return /*#__PURE__*/_jsx(Heatmap, _objectSpread({}, commonProps));
96
105
  case PLOT_TYPES.VIOLINPLOT:
97
- return /*#__PURE__*/React.createElement(Violin, _extends({
106
+ return /*#__PURE__*/_jsx(Violin, _objectSpread({
98
107
  mode: VIOLIN_MODES.MULTIKEY
99
108
  }, commonProps));
100
109
  case PLOT_TYPES.SCATTERPLOT:
101
110
  default:
102
- return /*#__PURE__*/React.createElement(Scatterplot, _extends({}, commonProps, {
111
+ return /*#__PURE__*/_jsx(Scatterplot, _objectSpread(_objectSpread({}, commonProps), {}, {
103
112
  isFullscreen: true
104
113
  }));
105
114
  }
106
115
  }, [plotType, showObsBtn, showVarsBtn]);
107
- return /*#__PURE__*/React.createElement("div", {
108
- className: "cherita-app"
109
- }, /*#__PURE__*/React.createElement(DatasetProvider, props, /*#__PURE__*/React.createElement(Container, {
110
- fluid: true,
111
- className: "cherita-app-container"
112
- }, /*#__PURE__*/React.createElement("div", {
113
- className: "cherita-app-obs modern-scrollbars border-end h-100"
114
- }, /*#__PURE__*/React.createElement(ObsColsList, _extends({}, props, {
115
- showSelectedAsActive: showSelectedAsActive,
116
- showHistograms: varMode === SELECTION_MODES.SINGLE,
117
- showColor: varMode === SELECTION_MODES.SINGLE
118
- }))), /*#__PURE__*/React.createElement("div", {
119
- className: "cherita-app-canvas"
120
- }, plot), /*#__PURE__*/React.createElement("div", {
121
- className: "cherita-app-sidebar p-3"
122
- }, /*#__PURE__*/React.createElement(Card, null, /*#__PURE__*/React.createElement(Card.Body, null, /*#__PURE__*/React.createElement("div", {
123
- className: "sidebar-plotselector"
124
- }, /*#__PURE__*/React.createElement(PlotTypeSelector, {
125
- currentType: plotType,
126
- onChange: type => setPlotType(type)
127
- })), plotType === PLOT_TYPES.SCATTERPLOT && isPseudospatial ? /*#__PURE__*/React.createElement("div", {
128
- className: "sidebar-pseudospatial"
129
- }, /*#__PURE__*/React.createElement(Pseudospatial, {
130
- plotType: pseudospatialPlotType,
131
- setPlotType: setpseudospatialPlotType,
132
- setShowControls: setShowPseudospatialControls
133
- })) : /*#__PURE__*/React.createElement(React.Fragment, null), /*#__PURE__*/React.createElement("div", {
134
- className: "sidebar-features"
135
- }, /*#__PURE__*/React.createElement(SearchBar, {
136
- searchDiseases: searchDiseases,
137
- searchVar: true
138
- }), /*#__PURE__*/React.createElement("div", {
139
- className: "sidebar-features-list"
140
- }, /*#__PURE__*/React.createElement(VarNamesList, {
141
- mode: varMode
142
- }))))))), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(Modal, {
143
- show: showModal,
144
- onHide: () => setShowModal(false),
145
- centered: true
146
- }, /*#__PURE__*/React.createElement(Modal.Header, {
147
- closeButton: true
148
- }), /*#__PURE__*/React.createElement(Modal.Body, null)), /*#__PURE__*/React.createElement(OffcanvasObs, _extends({}, props, {
149
- showSelectedAsActive: showSelectedAsActive,
150
- show: showObs,
151
- handleClose: () => setShowObs(false)
152
- })), /*#__PURE__*/React.createElement(OffcanvasVars, {
153
- show: showVars,
154
- handleClose: () => setShowVars(false),
155
- mode: varMode
156
- }), plotControls && /*#__PURE__*/React.createElement(OffcanvasControls, {
157
- show: showControls,
158
- handleClose: () => setShowControls(false),
159
- Controls: plotControls
160
- }), /*#__PURE__*/React.createElement(OffcanvasObsm, {
161
- show: showObsm,
162
- handleClose: () => setShowObsm(false)
163
- }), /*#__PURE__*/React.createElement(OffcanvasControls, {
164
- show: showPseudospatialControls,
165
- handleClose: () => setShowPseudospatialControls(false),
166
- Controls: PseudospatialToolbar,
167
- plotType: pseudospatialPlotType
168
- }))));
116
+ return /*#__PURE__*/_jsx("div", {
117
+ className: "cherita-app",
118
+ children: /*#__PURE__*/_jsxs(DatasetProvider, _objectSpread(_objectSpread({}, props), {}, {
119
+ children: [/*#__PURE__*/_jsxs(Container, {
120
+ fluid: true,
121
+ className: "cherita-app-container",
122
+ children: [/*#__PURE__*/_jsx("div", {
123
+ className: "cherita-app-obs modern-scrollbars border-end h-100",
124
+ children: /*#__PURE__*/_jsx(ObsColsList, _objectSpread(_objectSpread({}, props), {}, {
125
+ showSelectedAsActive: showSelectedAsActive,
126
+ showHistograms: varMode === SELECTION_MODES.SINGLE,
127
+ showColor: varMode === SELECTION_MODES.SINGLE
128
+ }))
129
+ }), /*#__PURE__*/_jsx("div", {
130
+ className: "cherita-app-canvas",
131
+ children: plot
132
+ }), /*#__PURE__*/_jsx("div", {
133
+ className: "cherita-app-sidebar p-3",
134
+ children: /*#__PURE__*/_jsx(Card, {
135
+ children: /*#__PURE__*/_jsxs(Card.Body, {
136
+ children: [/*#__PURE__*/_jsx("div", {
137
+ className: "plotselector",
138
+ children: /*#__PURE__*/_jsx(PlotTypeSelector, {
139
+ currentType: plotType,
140
+ onChange: type => setPlotType(type)
141
+ })
142
+ }), plotType === PLOT_TYPES.SCATTERPLOT && isPseudospatial ? /*#__PURE__*/_jsx("div", {
143
+ className: "sidebar-pseudospatial",
144
+ children: /*#__PURE__*/_jsx(Pseudospatial, {
145
+ plotType: pseudospatialPlotType,
146
+ setPlotType: setpseudospatialPlotType,
147
+ setShowControls: setShowPseudospatialControls
148
+ })
149
+ }) : /*#__PURE__*/_jsx(_Fragment, {}), /*#__PURE__*/_jsxs("div", {
150
+ className: "sidebar-features",
151
+ children: [/*#__PURE__*/_jsx(SearchBar, {
152
+ searchDiseases: searchDiseases,
153
+ searchVar: true
154
+ }), /*#__PURE__*/_jsx("div", {
155
+ className: "sidebar-features-list",
156
+ children: /*#__PURE__*/_jsx(VarNamesList, {
157
+ mode: varMode
158
+ })
159
+ })]
160
+ })]
161
+ })
162
+ })
163
+ })]
164
+ }), /*#__PURE__*/_jsxs("div", {
165
+ children: [/*#__PURE__*/_jsxs(Modal, {
166
+ show: showModal,
167
+ onHide: () => setShowModal(false),
168
+ centered: true,
169
+ children: [/*#__PURE__*/_jsx(Modal.Header, {
170
+ closeButton: true
171
+ }), /*#__PURE__*/_jsx(Modal.Body, {})]
172
+ }), /*#__PURE__*/_jsx(OffcanvasObs, _objectSpread(_objectSpread({}, props), {}, {
173
+ showSelectedAsActive: showSelectedAsActive,
174
+ show: showObs,
175
+ handleClose: () => setShowObs(false)
176
+ })), /*#__PURE__*/_jsx(OffcanvasVars, {
177
+ show: showVars,
178
+ handleClose: () => setShowVars(false),
179
+ mode: varMode
180
+ }), plotControls && /*#__PURE__*/_jsx(OffcanvasControls, {
181
+ show: showControls,
182
+ handleClose: () => setShowControls(false),
183
+ Controls: plotControls
184
+ }), /*#__PURE__*/_jsx(OffcanvasObsm, {
185
+ show: showObsm,
186
+ handleClose: () => setShowObsm(false)
187
+ }), /*#__PURE__*/_jsx(OffcanvasControls, {
188
+ show: showPseudospatialControls,
189
+ handleClose: () => setShowPseudospatialControls(false),
190
+ Controls: PseudospatialToolbar,
191
+ plotType: pseudospatialPlotType
192
+ })]
193
+ })]
194
+ }))
195
+ });
169
196
  }
@@ -0,0 +1,39 @@
1
+ import { useMediaQuery } from '@mui/material';
2
+ import { Alert } from 'react-bootstrap';
3
+ import { PlotTypeSelector } from './PlotTypeSelector';
4
+ import { BREAKPOINTS, PLOT_TYPES } from '../../constants/constants';
5
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
6
+ export function PlotAlert(_ref) {
7
+ let {
8
+ variant = 'warning',
9
+ plotType = PLOT_TYPES.SCATTERPLOT,
10
+ setPlotType,
11
+ heading,
12
+ children
13
+ } = _ref;
14
+ const XlBreakpoint = useMediaQuery(BREAKPOINTS.XL);
15
+ const showPlotSelector = XlBreakpoint;
16
+ return /*#__PURE__*/_jsxs(_Fragment, {
17
+ children: [showPlotSelector && /*#__PURE__*/_jsx("div", {
18
+ className: "plotselector",
19
+ children: /*#__PURE__*/_jsx(PlotTypeSelector, {
20
+ currentType: plotType,
21
+ onChange: type => {
22
+ if (setPlotType) setPlotType(type);
23
+ }
24
+ })
25
+ }), /*#__PURE__*/_jsx("div", {
26
+ className: "cherita-plot-alert h-100",
27
+ children: /*#__PURE__*/_jsx("div", {
28
+ className: "w-100 h-100 d-flex justify-content-center align-items-center",
29
+ children: /*#__PURE__*/_jsxs(Alert, {
30
+ variant: variant,
31
+ className: "m-0 w-75 w-lg-50 text-center",
32
+ children: [heading && /*#__PURE__*/_jsx(Alert.Heading, {
33
+ children: heading
34
+ }), " ", children]
35
+ })
36
+ })
37
+ })]
38
+ });
39
+ }
@@ -1,50 +1,95 @@
1
- import React from "react";
2
- import dotplotIcon from "../../../assets/images/plots/dotplot.svg";
3
- import heatmapIcon from "../../../assets/images/plots/heatmap.svg";
4
- import matrixplotIcon from "../../../assets/images/plots/matrixplot.svg";
5
- import scatterplotIcon from "../../../assets/images/plots/scatterplot.svg";
6
- import violinIcon from "../../../assets/images/plots/violin.svg";
7
- import { PLOT_TYPES } from "../../constants/constants";
8
- const iconMap = {
9
- [PLOT_TYPES.SCATTERPLOT]: scatterplotIcon,
10
- [PLOT_TYPES.MATRIXPLOT]: matrixplotIcon,
11
- [PLOT_TYPES.HEATMAP]: heatmapIcon,
12
- [PLOT_TYPES.DOTPLOT]: dotplotIcon,
13
- [PLOT_TYPES.VIOLINPLOT]: violinIcon
14
- };
15
- const plotTypes = Object.entries(iconMap).map(_ref => {
16
- let [type, icon] = _ref;
17
- return {
18
- type,
19
- icon,
20
- alt: type.charAt(0).toUpperCase() + type.slice(1)
21
- };
22
- });
23
- export function PlotTypeSelector(_ref2) {
1
+ 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; }
2
+ 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; }
3
+ function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
4
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
5
+ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
6
+ import { useState } from 'react';
7
+ import { PLOT_TYPES } from '../../constants/constants';
8
+ import { StyledTooltip } from '../../utils/StyledTooltip';
9
+ import DotPlotIcon from '../icons/DotPlotIcon';
10
+ import HeatmapIcon from '../icons/HeatmapIcon';
11
+ import MatrixPlotIcon from '../icons/MatrixPlotIcon';
12
+ import ScatterplotIcon from '../icons/ScatterplotIcon';
13
+ import ViolinPlotIcon from '../icons/ViolinPlotIcon';
14
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
15
+ const plotTypes = [{
16
+ type: PLOT_TYPES.SCATTERPLOT,
17
+ icon: ScatterplotIcon,
18
+ name: 'Scatterplot',
19
+ description: 'Displays cells in 2D based on dimensionality reduction.'
20
+ }, {
21
+ type: PLOT_TYPES.MATRIXPLOT,
22
+ icon: MatrixPlotIcon,
23
+ name: 'Matrix Plot',
24
+ description: 'Shows expression values of genes across categories.'
25
+ }, {
26
+ type: PLOT_TYPES.DOTPLOT,
27
+ icon: DotPlotIcon,
28
+ name: 'Dot Plot',
29
+ description: 'Shows proportion and expression of genes across groups.'
30
+ }, {
31
+ type: PLOT_TYPES.HEATMAP,
32
+ icon: HeatmapIcon,
33
+ name: 'Heatmap',
34
+ description: 'Visualises gene expression or feature activity as a colour-coded matrix.'
35
+ }, {
36
+ type: PLOT_TYPES.VIOLINPLOT,
37
+ icon: ViolinPlotIcon,
38
+ name: 'Violin Plot',
39
+ description: 'Displays distribution of gene expression across categories.'
40
+ }];
41
+ export function PlotTypeSelector(_ref) {
24
42
  let {
25
43
  currentType,
26
44
  onChange
27
- } = _ref2;
28
- return /*#__PURE__*/React.createElement("div", {
29
- className: "d-flex gap-2 justify-content-between"
30
- }, plotTypes.map(_ref3 => {
31
- let {
32
- type,
33
- icon,
34
- alt
35
- } = _ref3;
36
- return /*#__PURE__*/React.createElement("img", {
37
- key: type,
38
- src: icon,
39
- alt: alt,
40
- height: 32,
41
- width: 32,
42
- className: "plotselector-icon".concat(currentType === type ? " active" : ""),
43
- onClick: () => onChange(type),
44
- style: {
45
- borderBottom: currentType === type ? "2px solid #007bff" : "none"
46
- },
47
- title: alt
48
- });
45
+ } = _ref;
46
+ const [hoveredMap, setHoveredMap] = useState({});
47
+ const handleMouseEnter = type => setHoveredMap(prev => _objectSpread(_objectSpread({}, prev), {}, {
48
+ [type]: true
49
49
  }));
50
+ const handleMouseLeave = type => setHoveredMap(prev => _objectSpread(_objectSpread({}, prev), {}, {
51
+ [type]: false
52
+ }));
53
+ return /*#__PURE__*/_jsx("div", {
54
+ className: "d-flex gap-2 justify-content-between",
55
+ children: plotTypes.map(_ref2 => {
56
+ let {
57
+ type,
58
+ icon: Icon,
59
+ name,
60
+ description
61
+ } = _ref2;
62
+ const isActive = currentType === type;
63
+ const hovered = hoveredMap[type] || false;
64
+ const colour = isActive ? '#005a86' : hovered ? '#0071a7' : '#000';
65
+ return /*#__PURE__*/_jsx(StyledTooltip, {
66
+ title: /*#__PURE__*/_jsxs(_Fragment, {
67
+ children: [/*#__PURE__*/_jsx("strong", {
68
+ children: name
69
+ }), /*#__PURE__*/_jsx("br", {}), description]
70
+ }),
71
+ placement: "bottom",
72
+ slotProps: {
73
+ popper: {
74
+ modifiers: [{
75
+ name: 'offset',
76
+ options: {
77
+ offset: [0, -12]
78
+ }
79
+ }]
80
+ }
81
+ },
82
+ children: /*#__PURE__*/_jsx("div", {
83
+ onMouseEnter: () => handleMouseEnter(type),
84
+ onMouseLeave: () => handleMouseLeave(type),
85
+ onClick: () => onChange(type),
86
+ className: "plotselector-icon".concat(isActive ? ' active' : ''),
87
+ children: /*#__PURE__*/_jsx(Icon, {
88
+ size: 34,
89
+ colour: colour
90
+ })
91
+ })
92
+ }, type);
93
+ })
94
+ });
50
95
  }
@@ -3,28 +3,32 @@ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t =
3
3
  function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
4
4
  function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
5
5
  function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
6
- import React, { useCallback, useEffect, useRef, useState } from "react";
7
- import _ from "lodash";
8
- import { Alert, Button } from "react-bootstrap";
9
- import Plot from "react-plotly.js";
10
- import { PLOTLY_MODEBAR_BUTTONS } from "../../constants/constants";
11
- import { useDataset } from "../../context/DatasetContext";
12
- import { useFilteredData } from "../../context/FilterContext";
13
- import { useSettings } from "../../context/SettingsContext";
14
- import { LoadingSpinner } from "../../utils/LoadingIndicators";
15
- import { useDebouncedFetch } from "../../utils/requests";
16
- import { ControlsPlotlyToolbar, ObsPlotlyToolbar, VarPlotlyToolbar } from "../toolbar/Toolbar";
6
+ import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
7
+ import _ from 'lodash';
8
+ import { Button } from 'react-bootstrap';
9
+ import Plot from 'react-plotly.js';
10
+ import { PLOTLY_MODEBAR_BUTTONS } from '../../constants/constants';
11
+ import { useDataset } from '../../context/DatasetContext';
12
+ import { useFilteredData } from '../../context/FilterContext';
13
+ import { useSettings } from '../../context/SettingsContext';
14
+ import { LoadingSpinner } from '../../utils/LoadingIndicators';
15
+ import { useDebouncedFetch } from '../../utils/requests';
16
+ import { useSelectedMultiVar, useSelectedObs } from '../../utils/Resolver';
17
+ import { PlotAlert } from '../full-page/PlotAlert';
18
+ import { ControlsPlotlyToolbar, ObsPlotlyToolbar, VarPlotlyToolbar } from '../toolbar/Toolbar';
19
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
17
20
  export function Heatmap(_ref) {
18
- var _settings$selectedObs, _settings$selectedObs2, _settings$selectedObs3;
19
21
  let {
20
22
  showObsBtn = false,
21
23
  showVarsBtn = false,
22
24
  showCtrlsBtn = false,
23
25
  setShowObs,
24
26
  setShowVars,
25
- setShowControls
27
+ setShowControls,
28
+ plotType,
29
+ setPlotType
26
30
  } = _ref;
27
- const ENDPOINT = "heatmap";
31
+ const ENDPOINT = 'heatmap';
28
32
  const dataset = useDataset();
29
33
  const settings = useSettings();
30
34
  const {
@@ -35,44 +39,26 @@ export function Heatmap(_ref) {
35
39
  const [data, setData] = useState([]);
36
40
  const [layout, setLayout] = useState({});
37
41
  const [hasSelections, setHasSelections] = useState(false);
38
- const [params, setParams] = useState({
42
+ const selectedObs = useSelectedObs();
43
+ const selectedMultiVar = useSelectedMultiVar();
44
+ const params = useMemo(() => ({
39
45
  url: dataset.url,
40
- obsCol: settings.selectedObs,
41
- obsValues: !((_settings$selectedObs = settings.selectedObs) !== null && _settings$selectedObs !== void 0 && _settings$selectedObs.omit.length) ? null : _.difference(_.values((_settings$selectedObs2 = settings.selectedObs) === null || _settings$selectedObs2 === void 0 ? void 0 : _settings$selectedObs2.codes), (_settings$selectedObs3 = settings.selectedObs) === null || _settings$selectedObs3 === void 0 ? void 0 : _settings$selectedObs3.omit).map(c => {
42
- var _settings$selectedObs4;
43
- return (_settings$selectedObs4 = settings.selectedObs) === null || _settings$selectedObs4 === void 0 ? void 0 : _settings$selectedObs4.codesMap[c];
44
- }),
45
- varKeys: settings.selectedMultiVar.map(i => i.isSet ? {
46
+ obsCol: selectedObs,
47
+ obsValues: !(selectedObs !== null && selectedObs !== void 0 && selectedObs.omit.length) ? null : _.difference(selectedObs === null || selectedObs === void 0 ? void 0 : selectedObs.values, selectedObs === null || selectedObs === void 0 ? void 0 : selectedObs.omit),
48
+ varKeys: selectedMultiVar.map(i => i.isSet ? {
46
49
  name: i.name,
47
50
  indices: i.vars.map(v => v.index)
48
51
  } : i.index),
49
52
  obsIndices: isSliced ? [...(obsIndices || [])] : null,
50
53
  varNamesCol: dataset.varNamesCol
51
- });
54
+ }), [dataset.url, dataset.varNamesCol, isSliced, obsIndices, selectedMultiVar, selectedObs]);
52
55
  useEffect(() => {
53
- if (settings.selectedObs && settings.selectedMultiVar.length) {
56
+ if (selectedObs && selectedMultiVar.length) {
54
57
  setHasSelections(true);
55
58
  } else {
56
59
  setHasSelections(false);
57
60
  }
58
- setParams(p => {
59
- var _settings$selectedObs5, _settings$selectedObs6, _settings$selectedObs7;
60
- return _objectSpread(_objectSpread({}, p), {}, {
61
- url: dataset.url,
62
- obsCol: settings.selectedObs,
63
- obsValues: !((_settings$selectedObs5 = settings.selectedObs) !== null && _settings$selectedObs5 !== void 0 && _settings$selectedObs5.omit.length) ? null : _.difference(_.values((_settings$selectedObs6 = settings.selectedObs) === null || _settings$selectedObs6 === void 0 ? void 0 : _settings$selectedObs6.codes), (_settings$selectedObs7 = settings.selectedObs) === null || _settings$selectedObs7 === void 0 ? void 0 : _settings$selectedObs7.omit).map(c => {
64
- var _settings$selectedObs8;
65
- return (_settings$selectedObs8 = settings.selectedObs) === null || _settings$selectedObs8 === void 0 ? void 0 : _settings$selectedObs8.codesMap[c];
66
- }),
67
- varKeys: settings.selectedMultiVar.map(i => i.isSet ? {
68
- name: i.name,
69
- indices: i.vars.map(v => v.index)
70
- } : i.index),
71
- obsIndices: isSliced ? [...(obsIndices || [])] : null,
72
- varNamesCol: dataset.varNamesCol
73
- });
74
- });
75
- }, [settings.selectedMultiVar, settings.selectedObs, dataset.url, dataset.varNamesCol, obsIndices, isSliced]);
61
+ }, [selectedMultiVar, selectedObs, dataset.url, dataset.varNamesCol, obsIndices, isSliced]);
76
62
  const updateColorscale = useCallback(colorscale => {
77
63
  setLayout(l => {
78
64
  return _objectSpread(_objectSpread({}, l), {}, {
@@ -87,13 +73,16 @@ export function Heatmap(_ref) {
87
73
  isPending,
88
74
  serverError
89
75
  } = useDebouncedFetch(ENDPOINT, params, 500, {
90
- enabled: !!params.obsCol && !!params.varKeys.length
76
+ isEnabled: params => !!params.obsCol && !!params.varKeys.length
91
77
  });
92
78
  useEffect(() => {
93
- if (hasSelections && !isPending && !serverError) {
79
+ if (hasSelections && !!fetchedData && !isPending && !serverError) {
94
80
  setData(fetchedData.data);
95
81
  setLayout(fetchedData.layout);
96
82
  updateColorscale(colorscale.current);
83
+ } else {
84
+ setData([]);
85
+ setLayout({});
97
86
  }
98
87
  }, [fetchedData, hasSelections, isPending, serverError, updateColorscale]);
99
88
  useEffect(() => {
@@ -110,38 +99,50 @@ export function Heatmap(_ref) {
110
99
  const modeBarButtons = customModeBarButtons.length ? [customModeBarButtons, PLOTLY_MODEBAR_BUTTONS] : [PLOTLY_MODEBAR_BUTTONS];
111
100
  if (!serverError) {
112
101
  if (hasSelections) {
113
- return /*#__PURE__*/React.createElement("div", {
114
- className: "cherita-plot cherita-heatmap position-relative"
115
- }, isPending && /*#__PURE__*/React.createElement(LoadingSpinner, null), /*#__PURE__*/React.createElement(Plot, {
116
- data: data,
117
- layout: layout,
118
- useResizeHandler: true,
119
- style: {
120
- width: "100%",
121
- height: "100%"
122
- },
123
- config: {
124
- displaylogo: false,
125
- modeBarButtons: modeBarButtons
126
- }
127
- }));
102
+ return /*#__PURE__*/_jsxs("div", {
103
+ className: "cherita-plot cherita-heatmap position-relative",
104
+ children: [isPending && /*#__PURE__*/_jsx(LoadingSpinner, {}), /*#__PURE__*/_jsx(Plot, {
105
+ data: data,
106
+ layout: layout,
107
+ useResizeHandler: true,
108
+ style: {
109
+ width: '100%',
110
+ height: '100%'
111
+ },
112
+ config: {
113
+ displaylogo: false,
114
+ modeBarButtons: modeBarButtons
115
+ }
116
+ })]
117
+ });
128
118
  }
129
- return /*#__PURE__*/React.createElement("div", {
130
- className: "cherita-heatmap"
131
- }, /*#__PURE__*/React.createElement(Alert, {
132
- variant: "light"
133
- }, "Select", " ", showVarsBtn ? /*#__PURE__*/React.createElement(Button, {
134
- variant: "link",
135
- className: "border-0 p-0 align-baseline",
136
- onClick: setShowVars
137
- }, "features") : "features", " ", "and a", " ", showObsBtn ? /*#__PURE__*/React.createElement(Button, {
138
- variant: "link",
139
- className: "border-0 p-0 align-baseline",
140
- onClick: setShowObs
141
- }, "category") : "category"));
119
+ return /*#__PURE__*/_jsx(PlotAlert, {
120
+ variant: "info",
121
+ heading: "Set up your heatmap",
122
+ plotType: plotType,
123
+ setPlotType: setPlotType,
124
+ children: /*#__PURE__*/_jsxs("p", {
125
+ className: "p-0 m-0",
126
+ children: ["Select one or more", ' ', showVarsBtn ? /*#__PURE__*/_jsx(Button, {
127
+ variant: "link",
128
+ className: "border-0 p-0 align-baseline",
129
+ onClick: setShowVars,
130
+ children: "features"
131
+ }) : 'features', ' ', "to display their expression, then choose a", ' ', showObsBtn ? /*#__PURE__*/_jsx(Button, {
132
+ variant: "link",
133
+ className: "border-0 p-0 align-baseline",
134
+ onClick: setShowObs,
135
+ children: "category"
136
+ }) : 'category', ' ', "to group observations in the heatmap."]
137
+ })
138
+ });
142
139
  } else {
143
- return /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(Alert, {
144
- variant: "danger"
145
- }, serverError.message));
140
+ return /*#__PURE__*/_jsx(PlotAlert, {
141
+ variant: "danger",
142
+ heading: "Error displaying the heatmap",
143
+ plotType: plotType,
144
+ setPlotType: setPlotType,
145
+ children: serverError.message || 'An unexpected error occurred while generating the plot.'
146
+ });
146
147
  }
147
148
  }