@haniffalab/cherita-react 0.2.0-dev.2024-12-16.ab9c5057 → 0.2.0-dev.2024-12-16.67617f27

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 (32) hide show
  1. package/dist/components/dotplot/Dotplot.js +6 -1
  2. package/dist/components/full-page/FullPage.js +81 -7
  3. package/dist/components/heatmap/Heatmap.js +6 -1
  4. package/dist/components/matrixplot/Matrixplot.js +6 -1
  5. package/dist/components/obs-list/ObsItem.js +74 -24
  6. package/dist/components/obs-list/ObsList.js +27 -5
  7. package/dist/components/pseudospatial/Pseudospatial.js +219 -0
  8. package/dist/components/pseudospatial/PseudospatialControls.js +12 -0
  9. package/dist/components/pseudospatial/PseudospatialToolbar.js +157 -0
  10. package/dist/components/scatterplot/Scatterplot.js +100 -166
  11. package/dist/components/var-list/VarItem.js +35 -53
  12. package/dist/components/var-list/VarList.js +4 -2
  13. package/dist/components/var-list/VarSet.js +1 -0
  14. package/dist/components/violin/Violin.js +7 -2
  15. package/dist/constants/constants.js +17 -1
  16. package/dist/context/DatasetContext.js +40 -2
  17. package/dist/css/cherita.css +44 -0
  18. package/dist/css/cherita.css.map +1 -1
  19. package/dist/helpers/color-helper.js +12 -8
  20. package/dist/helpers/zarr-helper.js +2 -0
  21. package/dist/index.js +25 -0
  22. package/dist/utils/Filter.js +129 -0
  23. package/dist/utils/Histogram.js +54 -0
  24. package/dist/utils/ImageViewer.js +40 -0
  25. package/dist/{components/scatterplot → utils}/Legend.js +12 -7
  26. package/dist/utils/VirtualizedList.js +2 -2
  27. package/dist/utils/requests.js +8 -2
  28. package/dist/utils/search.js +4 -2
  29. package/dist/utils/string.js +7 -3
  30. package/package.json +2 -2
  31. package/scss/cherita.scss +44 -0
  32. package/dist/App.scss +0 -270
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.Histogram = Histogram;
7
+ var _react = _interopRequireDefault(require("react"));
8
+ var _xCharts = require("@mui/x-charts");
9
+ var _lodash = _interopRequireDefault(require("lodash"));
10
+ var _LoadingIndicators = require("./LoadingIndicators");
11
+ var _string = require("./string");
12
+ var _jsxRuntime = require("react/jsx-runtime");
13
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
14
+ function Histogram(_ref) {
15
+ let {
16
+ data,
17
+ isPending,
18
+ altColor = false
19
+ } = _ref;
20
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
21
+ className: "feature-histogram-container",
22
+ children: isPending ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_LoadingIndicators.LoadingLinear, {}) : data ? /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
23
+ className: "feature-histogram m-1",
24
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_xCharts.SparkLineChart, {
25
+ plotType: "bar",
26
+ data: data.log10,
27
+ margin: {
28
+ top: 0,
29
+ right: 0,
30
+ bottom: 0,
31
+ left: 0
32
+ },
33
+ colors: altColor ? _xCharts.mangoFusionPalette : _xCharts.blueberryTwilightPalette,
34
+ showHighlight: true,
35
+ showTooltip: true,
36
+ valueFormatter: (v, _ref2) => {
37
+ let {
38
+ dataIndex
39
+ } = _ref2;
40
+ return `${(0, _string.formatNumerical)(data.hist[dataIndex])}`;
41
+ },
42
+ xAxis: {
43
+ data: _lodash.default.range(data.bin_edges?.length) || null,
44
+ valueFormatter: v => `Bin [${(0, _string.formatNumerical)(data.bin_edges[v][0], _string.FORMATS.EXPONENTIAL)}, ${(0, _string.formatNumerical)(data.bin_edges[v][1], _string.FORMATS.EXPONENTIAL)}${v === data.bin_edges.length - 1 ? "]" : ")"}`
45
+ },
46
+ slotProps: {
47
+ popper: {
48
+ className: "feature-histogram-tooltip"
49
+ }
50
+ }
51
+ })
52
+ }) : null
53
+ });
54
+ }
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.ImageViewer = void 0;
7
+ var _react = _interopRequireWildcard(require("react"));
8
+ var _reactBootstrap = require("react-bootstrap");
9
+ var _jsxRuntime = require("react/jsx-runtime");
10
+ function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
11
+ function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
12
+ const ImageViewer = _ref => {
13
+ let {
14
+ src,
15
+ alt,
16
+ className = "img-fluid"
17
+ } = _ref;
18
+ const [error, setError] = (0, _react.useState)(false);
19
+ const handleError = () => {
20
+ console.error("Error loading image from src:", src);
21
+ setError(true);
22
+ };
23
+ if (!error) {
24
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)("img", {
25
+ src: src,
26
+ alt: alt,
27
+ className: className,
28
+ loading: "lazy",
29
+ onError: handleError
30
+ });
31
+ } else {
32
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_jsxRuntime.Fragment, {
33
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Alert, {
34
+ variant: "danger",
35
+ children: "Failed to load image"
36
+ })
37
+ });
38
+ }
39
+ };
40
+ exports.ImageViewer = ImageViewer;
@@ -6,17 +6,18 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.Legend = Legend;
7
7
  var _react = require("react");
8
8
  var _lodash = _interopRequireDefault(require("lodash"));
9
- var _constants = require("../../constants/constants");
10
- var _DatasetContext = require("../../context/DatasetContext");
11
- var _colorHelper = require("../../helpers/color-helper");
12
- var _string = require("../../utils/string");
9
+ var _string = require("./string");
10
+ var _constants = require("../constants/constants");
11
+ var _DatasetContext = require("../context/DatasetContext");
12
+ var _colorHelper = require("../helpers/color-helper");
13
13
  var _jsxRuntime = require("react/jsx-runtime");
14
14
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
15
15
  function Legend(_ref) {
16
16
  let {
17
17
  isCategorical = false,
18
18
  min = 0,
19
- max = 1
19
+ max = 1,
20
+ colorscale = null
20
21
  } = _ref;
21
22
  const dataset = (0, _DatasetContext.useDataset)();
22
23
  const {
@@ -24,7 +25,11 @@ function Legend(_ref) {
24
25
  } = (0, _colorHelper.useColor)();
25
26
  const spanList = (0, _react.useMemo)(() => {
26
27
  return _lodash.default.range(100).map(i => {
27
- var color = (0, _colorHelper.rgbToHex)(getColor(i / 100, isCategorical));
28
+ var color = (0, _colorHelper.rgbToHex)(getColor({
29
+ value: i / 100,
30
+ categorical: isCategorical,
31
+ colorscale: colorscale
32
+ }));
28
33
  return /*#__PURE__*/(0, _jsxRuntime.jsx)("span", {
29
34
  className: "grad-step",
30
35
  style: {
@@ -32,7 +37,7 @@ function Legend(_ref) {
32
37
  }
33
38
  }, i);
34
39
  });
35
- }, [getColor, isCategorical]);
40
+ }, [colorscale, getColor, isCategorical]);
36
41
  if (dataset.colorEncoding && !isCategorical) {
37
42
  return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
38
43
  className: "cherita-legend",
@@ -14,7 +14,7 @@ function VirtualizedList(_ref) {
14
14
  getDataAtIndex,
15
15
  count,
16
16
  ItemComponent,
17
- estimateSize = 44,
17
+ estimateSize = 45,
18
18
  overscan = 25,
19
19
  maxHeight = "80vh",
20
20
  ...props
@@ -32,7 +32,7 @@ function VirtualizedList(_ref) {
32
32
  const virtualItems = itemVirtualizer.getVirtualItems();
33
33
  (0, _react.useEffect)(() => {
34
34
  itemVirtualizer.measure();
35
- }, [itemVirtualizer, parentNode?.clientHeight]);
35
+ }, [itemVirtualizer, parentNode?.clientHeight, getDataAtIndex]);
36
36
  return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
37
37
  ref: refCallback,
38
38
  style: {
@@ -42,7 +42,10 @@ async function fetchData(endpoint, params) {
42
42
  return await response.json();
43
43
  }
44
44
  const useFetch = function (endpoint, params) {
45
- let opts = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
45
+ let opts = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {
46
+ refetchOnMount: false,
47
+ refetchOnWindowFocus: false
48
+ };
46
49
  let apiUrl = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
47
50
  const {
48
51
  enabled = true
@@ -74,7 +77,10 @@ const useFetch = function (endpoint, params) {
74
77
  exports.useFetch = useFetch;
75
78
  const useDebouncedFetch = function (endpoint, params) {
76
79
  let delay = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 500;
77
- let opts = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
80
+ let opts = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {
81
+ refetchOnMount: false,
82
+ refetchOnWindowFocus: false
83
+ };
78
84
  let apiUrl = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : null;
79
85
  const {
80
86
  enabled = true
@@ -16,7 +16,8 @@ const useDiseaseSearch = () => {
16
16
  text: ""
17
17
  });
18
18
  const data = (0, _requests.useFetch)(ENDPOINT, params, {
19
- enabled: !!params.text.length
19
+ enabled: !!params.text.length,
20
+ refetchOnMount: true
20
21
  });
21
22
  return {
22
23
  params,
@@ -34,7 +35,8 @@ const useVarSearch = () => {
34
35
  text: ""
35
36
  });
36
37
  const data = (0, _requests.useFetch)(ENDPOINT, params, {
37
- enabled: !!params.text.length
38
+ enabled: !!params.text.length,
39
+ refetchOnMount: true
38
40
  });
39
41
  return {
40
42
  params,
@@ -5,6 +5,7 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.FORMATS = void 0;
7
7
  exports.formatNumerical = formatNumerical;
8
+ exports.formatString = formatString;
8
9
  var _numbro = _interopRequireDefault(require("numbro"));
9
10
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
10
11
  const FORMATS = exports.FORMATS = {
@@ -39,10 +40,10 @@ function formatAbbreviation(n) {
39
40
  function formatNumerical(n) {
40
41
  let format = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : FORMATS.THOUSAND;
41
42
  let precision = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 3;
42
- if (isNaN(n)) {
43
- return "NaN";
44
- } else if (n === 0) {
43
+ if (n === 0) {
45
44
  return "0";
45
+ } else if (!n || n === undefined || isNaN(n)) {
46
+ return "NaN";
46
47
  }
47
48
  switch (format) {
48
49
  case FORMATS.EXPONENTIAL:
@@ -61,4 +62,7 @@ function formatNumerical(n) {
61
62
  default:
62
63
  return formatThousand(n, precision);
63
64
  }
65
+ }
66
+ function formatString(s) {
67
+ return s.trim().replace(/_/g, " ");
64
68
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@haniffalab/cherita-react",
3
- "version": "0.2.0-dev.2024-12-16.ab9c5057",
3
+ "version": "0.2.0-dev.2024-12-16.67617f27",
4
4
  "author": "",
5
5
  "license": "",
6
6
  "main": "dist/index.js",
@@ -101,5 +101,5 @@
101
101
  "url": "https://github.com/haniffalab/cherita-react/issues"
102
102
  },
103
103
  "homepage": "https://github.com/haniffalab/cherita-react#readme",
104
- "prereleaseSha": "ab9c5057639276863637b6dd046ba3dcbc3b6804"
104
+ "prereleaseSha": "67617f278b24035c633eed30a5b4d0136e3f77bb"
105
105
  }
package/scss/cherita.scss CHANGED
@@ -128,6 +128,10 @@
128
128
  background-color: #cce3ed;
129
129
  }
130
130
 
131
+ .obs-item {
132
+ box-sizing: border-box;
133
+ }
134
+
131
135
  .obs-value-list-check {
132
136
  padding-right: 1rem;
133
137
  word-break: auto-phrase;
@@ -268,6 +272,7 @@
268
272
  @extend .col-xxl-6;
269
273
 
270
274
  position: relative;
275
+ max-height: 100%;
271
276
  }
272
277
 
273
278
  .cherita-app-obs {
@@ -308,3 +313,42 @@
308
313
  .caret-off .dropdown-toggle::after {
309
314
  display: none;
310
315
  }
316
+
317
+ .cherita-pseudospatial {
318
+ width: 100%;
319
+ }
320
+
321
+ .cherita-pseudospatial-plot {
322
+ width: 100%;
323
+ height: 100%;
324
+ }
325
+
326
+ .cherita-pseudospatial-toolbar {
327
+ display: flex;
328
+ flex-direction: column;
329
+ }
330
+
331
+ /* Add a bottom border to the last item in the Accordion */
332
+ .accordion-flush .accordion-item:last-child {
333
+ border-bottom: 1px solid #dee2e6; /* Adjust the color and width as needed */
334
+ }
335
+
336
+ .var-disease-info-collapse {
337
+ max-height: 40vh;
338
+ overflow-y: auto;
339
+ }
340
+
341
+ .cherita-scatterplot #deckgl-wrapper {
342
+ z-index: 1 !important;
343
+ }
344
+
345
+ .tooltip-grayout {
346
+ color: #a0a7b4 !important;
347
+ background-color: #3a424b !important;
348
+ opacity: 0.8;
349
+ z-index: 100 !important;
350
+ }
351
+
352
+ .deck-tooltip {
353
+ z-index: 100 !important;
354
+ }
package/dist/App.scss DELETED
@@ -1,270 +0,0 @@
1
- // Theme CSS
2
- $accordion-button-active-bg: #e7edf0;
3
-
4
- @import "bootstrap/scss/bootstrap";
5
-
6
- input[type="checkbox"], .cursor-pointer {
7
- cursor: pointer;
8
- }
9
-
10
- .loading-spinner {
11
- @extend .bg-light;
12
- height: 100%;
13
- width: 100%;
14
- display: flex;
15
- z-index: 1;
16
- opacity: 75%;
17
- position: absolute;
18
- justify-content: center;
19
- align-items: center;
20
- }
21
-
22
- .cherita-container {
23
- margin: 40px auto;
24
- background-color: #fff;
25
- border-radius: 0.25rem;
26
- box-shadow: 0 0.5em 1em 0.3em rgba(10, 10, 10, .15), 0 0 0 1px rgba(10, 10, 10, .02);
27
- color: #4a4a4a;
28
- max-width: 100%;
29
- position: relative;
30
- overflow: hidden;
31
- }
32
-
33
- .cherita-navbar {
34
- @extend .mx-1;
35
- @extend .my-2;
36
- position: absolute;
37
- z-index: 11;
38
- top: 0;
39
- left: 0;
40
- right: 0;
41
- border-radius: 0.25rem;
42
- }
43
-
44
- .cherita-container .cherita-navbar-item>.dropdown-menu {
45
- height: var(--dropdown-height);
46
- overflow-x: hidden;
47
- overflow-y: scroll;
48
- }
49
-
50
- /* Scrollbar styling */
51
-
52
- /* Works on Firefox */
53
- .cherita-container * {
54
- scrollbar-width: thin;
55
- scrollbar-color: rgb(70, 70, 70) auto;
56
- }
57
-
58
- /* Works on Chrome, Edge, and Safari */
59
- .cherita-container *::-webkit-scrollbar {
60
- width: 7px;
61
- }
62
-
63
- .cherita-container *::-webkit-scrollbar-track {
64
- background: #212529;
65
- }
66
-
67
- .cherita-container *::-webkit-scrollbar-thumb {
68
- background-color: rgb(70, 70, 70);
69
- }
70
-
71
- /* End scrollbar styling*/
72
-
73
- .cherita-container-plot {
74
- margin-top: 76px;
75
- padding: 20px;
76
- position: relative;
77
- min-height: 500px;
78
- }
79
-
80
- .cherita-container-scatterplot {
81
- position: relative;
82
- min-height: 500px;
83
- height: 100%;
84
- }
85
-
86
- .cherita-spatial-controls {
87
- position: absolute;
88
- z-index: 10;
89
- top: 1rem;
90
- left: 1rem;
91
- width: 3rem;
92
- }
93
-
94
- .cherita-spatial-footer {
95
- position: absolute;
96
- z-index: 10;
97
- bottom: 1rem;
98
- display: flex;
99
- justify-content: space-between;
100
- align-items: flex-end;
101
- flex-wrap: wrap;
102
- width: 100%;
103
- padding-left: 2rem;
104
- padding-right: 2rem;
105
- padding-bottom: 1rem;
106
- pointer-events: none;
107
- > * {
108
- pointer-events: auto;
109
- }
110
- }
111
-
112
- .cherita-toolbox-footer {
113
- display: flex;
114
- flex-direction: column;
115
- }
116
-
117
- .cherita-toolbox-footer .alert {
118
- width: fit-content;
119
- }
120
-
121
- .cherita-toolbox {
122
- order: 1;
123
- }
124
-
125
- .cherita-legend {
126
- order: 2;
127
- width: 12rem;
128
- }
129
-
130
- @include media-breakpoint-down(xl) {
131
- .cherita-spatial-controls {
132
- top: 100px;
133
- }
134
- }
135
-
136
- .cherita-accordion-active .accordion-button {
137
- background-color: rgb(204, 227, 237)
138
- }
139
-
140
- .obs-value-list-check {
141
- padding-right: 1rem;
142
- word-break: auto-phrase;
143
- overflow-wrap: anywhere;
144
- }
145
-
146
- .grad-step {
147
- display: inline-block;
148
- height: 20px;
149
- width: 1%;
150
- }
151
- .gradient {
152
- width: 100%;
153
- white-space: nowrap;
154
- position: relative;
155
- display: inline-block;
156
- top: 4px;
157
- padding-bottom: 15px;
158
- }
159
-
160
- .gradient .domain-min {
161
- position: absolute;
162
- left: 0;
163
- font-size: 11px;
164
- bottom: 3px;
165
- }
166
- .gradient .domain-med {
167
- position: absolute;
168
- right: 25%;
169
- left: 25%;
170
- text-align: center;
171
- font-size: 11px;
172
- bottom: 3px;
173
- }
174
- .gradient .domain-max {
175
- position: absolute;
176
- right: 0;
177
- font-size: 11px;
178
- bottom: 3px;
179
- }
180
-
181
- .cm-string {
182
- padding: 0px 4px;
183
- display: inline-block;
184
- min-width: 13px;
185
- min-height: 13px;
186
- border-radius: 3px;
187
- box-sizing: border-box;
188
- position: relative;
189
- vertical-align: middle;
190
- margin-left: 2px;
191
- margin-bottom: 2px;
192
- position: relative;
193
- top: 1px;
194
- }
195
- .cm-small {
196
- height: 15px;
197
- width: 15px;
198
- }
199
-
200
- .obs-distribution {
201
- width: 100%;
202
- height: 4rem;
203
- }
204
-
205
- .obs-continuous-stats {
206
- font-weight: lighter;
207
- margin: 0;
208
- }
209
-
210
- .value-count-badge {
211
- color: black !important;
212
- background-color: rgb(222, 222, 222) !important;
213
- }
214
-
215
- .value-pct-gauge-container {
216
- width: 1.5rem;
217
- height: 1.5rem;
218
- padding: 0.2rem;
219
- }
220
-
221
- .feature-histogram-container {
222
- height: 1.25rem;
223
- width: 5rem;
224
- display: flex;
225
- align-items: center;
226
- }
227
-
228
- .feature-histogram {
229
- @extend .feature-histogram-container;
230
- background-color: rgb(222, 222, 222);
231
- }
232
-
233
- .feature-histogram-tooltip .MuiChartsTooltip-markCell,.MuiChartsTooltip-labelCell {
234
- display: none;
235
- }
236
-
237
- .feature-histogram-tooltip .MuiChartsTooltip-valueCell {
238
- padding: 0.5rem !important;
239
- }
240
-
241
- .feature-histogram-tooltip .MuiChartsTooltip-valueCell > p {
242
- font-size: 0.85rem !important;
243
- }
244
-
245
- .feature-histogram-tooltip td > p {
246
- font-size: 0.85rem !important;
247
- }
248
-
249
- .feature-disease-info {
250
- font-weight: lighter;
251
- border-top: 1px solid var(list-group-border-color);
252
- border-right: 0;
253
- border-left: 0;
254
- border-bottom: 0;
255
- }
256
-
257
- .feature-disease-info table {
258
- margin: 0;
259
- }
260
-
261
- .var-list-toolbar {
262
- display: flex;
263
- justify-content: space-between;
264
- align-items: center;
265
- height: 3rem;
266
- }
267
-
268
- .var-list-toolbar .svg-inline--fa {
269
- height: 1.2rem;
270
- }