@haniffalab/cherita-react 1.3.0 → 1.3.1

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 (137) 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 +85 -57
  4. package/dist/cjs/components/dotplot/DotplotControls.js +103 -83
  5. package/dist/cjs/components/full-page/FullPage.js +167 -114
  6. package/dist/cjs/components/full-page/PlotAlert.js +45 -0
  7. package/dist/cjs/components/full-page/PlotTypeSelector.js +102 -0
  8. package/dist/cjs/components/heatmap/Heatmap.js +83 -53
  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 +83 -54
  18. package/dist/cjs/components/matrixplot/MatrixplotControls.js +8 -5
  19. package/dist/cjs/components/obs-list/ObsItem.js +305 -216
  20. package/dist/cjs/components/obs-list/ObsList.js +164 -128
  21. package/dist/cjs/components/obs-list/ObsToolbar.js +2 -3
  22. package/dist/cjs/components/obsm-list/ObsmList.js +67 -28
  23. package/dist/cjs/components/offcanvas/index.js +62 -27
  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 +223 -175
  27. package/dist/cjs/components/scatterplot/ScatterplotControls.js +45 -31
  28. package/dist/cjs/components/scatterplot/SpatialControls.js +143 -116
  29. package/dist/cjs/components/scatterplot/Toolbox.js +41 -30
  30. package/dist/cjs/components/search-bar/SearchBar.js +176 -120
  31. package/dist/cjs/components/search-bar/SearchInfo.js +79 -85
  32. package/dist/cjs/components/search-bar/SearchResults.js +93 -71
  33. package/dist/cjs/components/toolbar/Toolbar.js +111 -0
  34. package/dist/cjs/components/var-list/VarItem.js +131 -103
  35. package/dist/cjs/components/var-list/VarList.js +96 -74
  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 +124 -81
  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 +54 -39
  42. package/dist/cjs/context/DatasetContext.js +27 -17
  43. package/dist/cjs/context/FilterContext.js +11 -9
  44. package/dist/cjs/context/SettingsContext.js +339 -125
  45. package/dist/cjs/context/ZarrDataContext.js +6 -5
  46. package/dist/cjs/helpers/color-helper.js +2 -2
  47. package/dist/cjs/helpers/map-helper.js +2 -1
  48. package/dist/cjs/helpers/zarr-helper.js +3 -3
  49. package/dist/cjs/index.js +15 -21
  50. package/dist/cjs/utils/Filter.js +16 -11
  51. package/dist/cjs/utils/Histogram.js +35 -33
  52. package/dist/cjs/utils/ImageViewer.js +11 -8
  53. package/dist/cjs/utils/Legend.js +37 -30
  54. package/dist/cjs/utils/LoadingIndicators.js +15 -13
  55. package/dist/cjs/utils/Resolver.js +213 -0
  56. package/dist/cjs/utils/Skeleton.js +10 -10
  57. package/dist/cjs/utils/StyledTooltip.js +44 -0
  58. package/dist/cjs/utils/VirtualizedList.js +36 -29
  59. package/dist/cjs/utils/errors.js +15 -15
  60. package/dist/cjs/utils/requests.js +21 -9
  61. package/dist/cjs/utils/search.js +4 -4
  62. package/dist/cjs/utils/string.js +6 -6
  63. package/dist/cjs/utils/zarrData.js +20 -21
  64. package/dist/css/cherita.css +188 -65
  65. package/dist/css/cherita.css.map +1 -1
  66. package/dist/esm/components/controls/Controls.js +43 -35
  67. package/dist/esm/components/dotplot/Dotplot.js +93 -64
  68. package/dist/esm/components/dotplot/DotplotControls.js +106 -85
  69. package/dist/esm/components/full-page/FullPage.js +180 -124
  70. package/dist/esm/components/full-page/PlotAlert.js +39 -0
  71. package/dist/esm/components/full-page/PlotTypeSelector.js +95 -0
  72. package/dist/esm/components/heatmap/Heatmap.js +91 -60
  73. package/dist/esm/components/heatmap/HeatmapControls.js +8 -4
  74. package/dist/esm/components/icons/DotPlotIcon.js +58 -0
  75. package/dist/esm/components/icons/HeatmapIcon.js +39 -0
  76. package/dist/esm/components/icons/MatrixPlotIcon.1.js +51 -0
  77. package/dist/esm/components/icons/MatrixPlotIcon.js +53 -0
  78. package/dist/esm/components/icons/ScatterplotIcon.1.js +158 -0
  79. package/dist/esm/components/icons/ScatterplotIcon.js +138 -0
  80. package/dist/esm/components/icons/ViolinPlotIcon.js +36 -0
  81. package/dist/esm/components/matrixplot/Matrixplot.js +91 -61
  82. package/dist/esm/components/matrixplot/MatrixplotControls.js +10 -6
  83. package/dist/esm/components/obs-list/ObsItem.js +320 -228
  84. package/dist/esm/components/obs-list/ObsList.js +179 -142
  85. package/dist/esm/components/obs-list/ObsToolbar.js +3 -3
  86. package/dist/esm/components/obsm-list/ObsmList.js +71 -32
  87. package/dist/esm/components/offcanvas/index.js +68 -33
  88. package/dist/esm/components/pseudospatial/Pseudospatial.js +145 -88
  89. package/dist/esm/components/pseudospatial/PseudospatialToolbar.js +127 -78
  90. package/dist/esm/components/scatterplot/Scatterplot.js +243 -194
  91. package/dist/esm/components/scatterplot/ScatterplotControls.js +50 -35
  92. package/dist/esm/components/scatterplot/SpatialControls.js +155 -127
  93. package/dist/esm/components/scatterplot/Toolbox.js +44 -32
  94. package/dist/esm/components/search-bar/SearchBar.js +187 -130
  95. package/dist/esm/components/search-bar/SearchInfo.js +86 -91
  96. package/dist/esm/components/search-bar/SearchResults.js +100 -77
  97. package/dist/esm/components/toolbar/Toolbar.js +101 -0
  98. package/dist/esm/components/var-list/VarItem.js +142 -113
  99. package/dist/esm/components/var-list/VarList.js +108 -88
  100. package/dist/esm/components/var-list/VarListToolbar.js +64 -58
  101. package/dist/esm/components/var-list/VarSet.js +134 -115
  102. package/dist/esm/components/violin/Violin.js +135 -91
  103. package/dist/esm/components/violin/ViolinControls.js +10 -6
  104. package/dist/esm/constants/colorscales.js +19 -19
  105. package/dist/esm/constants/constants.js +53 -38
  106. package/dist/esm/context/DatasetContext.js +34 -23
  107. package/dist/esm/context/FilterContext.js +11 -8
  108. package/dist/esm/context/SettingsContext.js +341 -126
  109. package/dist/esm/context/ZarrDataContext.js +8 -6
  110. package/dist/esm/helpers/color-helper.js +5 -5
  111. package/dist/esm/helpers/map-helper.js +4 -3
  112. package/dist/esm/helpers/zarr-helper.js +6 -6
  113. package/dist/esm/index.js +22 -22
  114. package/dist/esm/utils/Filter.js +22 -17
  115. package/dist/esm/utils/Histogram.js +39 -37
  116. package/dist/esm/utils/ImageViewer.js +12 -8
  117. package/dist/esm/utils/Legend.js +44 -36
  118. package/dist/esm/utils/LoadingIndicators.js +16 -13
  119. package/dist/esm/utils/Resolver.js +201 -0
  120. package/dist/esm/utils/Skeleton.js +11 -10
  121. package/dist/esm/utils/StyledTooltip.js +38 -0
  122. package/dist/esm/utils/VirtualizedList.js +37 -29
  123. package/dist/esm/utils/errors.js +15 -15
  124. package/dist/esm/utils/requests.js +24 -12
  125. package/dist/esm/utils/search.js +7 -7
  126. package/dist/esm/utils/string.js +7 -7
  127. package/dist/esm/utils/zarrData.js +27 -28
  128. package/package.json +21 -8
  129. package/scss/cherita-bootstrap.scss +2 -2
  130. package/scss/cherita.scss +65 -17
  131. package/scss/components/accordions.scss +15 -2
  132. package/scss/components/layouts.scss +116 -30
  133. package/scss/components/lists.scss +16 -5
  134. package/scss/components/plotly.scss +40 -23
  135. package/scss/components/plots.scss +14 -1
  136. package/dist/cjs/components/full-page/FullPagePseudospatial.js +0 -157
  137. package/dist/esm/components/full-page/FullPagePseudospatial.js +0 -149
@@ -3,23 +3,24 @@ 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, useMemo, useState } from "react";
7
- import { Tooltip } from "@mui/material";
8
- import { Gauge, SparkLineChart } from "@mui/x-charts";
9
- import _ from "lodash";
10
- import { Badge, Form, ListGroup } from "react-bootstrap";
11
- import { ObsToolbar } from "./ObsToolbar";
12
- import { COLOR_ENCODINGS, OBS_TYPES } from "../../constants/constants";
13
- import { useDataset } from "../../context/DatasetContext";
14
- import { useFilteredData } from "../../context/FilterContext";
15
- import { useSettings } from "../../context/SettingsContext";
16
- import { useColor } from "../../helpers/color-helper";
17
- import { Histogram } from "../../utils/Histogram";
18
- import { LoadingLinear } from "../../utils/LoadingIndicators";
19
- import { useFetch } from "../../utils/requests";
20
- import { formatNumerical, FORMATS } from "../../utils/string";
21
- import { VirtualizedList } from "../../utils/VirtualizedList";
22
- import { useObsData } from "../../utils/zarrData";
6
+ import { useCallback, useEffect, useMemo, useState } from 'react';
7
+ import { Tooltip } from '@mui/material';
8
+ import { Gauge, SparkLineChart } from '@mui/x-charts';
9
+ import _ from 'lodash';
10
+ import { Badge, Form, ListGroup } from 'react-bootstrap';
11
+ import { ObsToolbar } from './ObsToolbar';
12
+ import { COLOR_ENCODINGS, OBS_TYPES } from '../../constants/constants';
13
+ import { useDataset } from '../../context/DatasetContext';
14
+ import { useFilteredData } from '../../context/FilterContext';
15
+ import { useSettings } from '../../context/SettingsContext';
16
+ import { useColor } from '../../helpers/color-helper';
17
+ import { Histogram } from '../../utils/Histogram';
18
+ import { LoadingLinear } from '../../utils/LoadingIndicators';
19
+ import { useFetch } from '../../utils/requests';
20
+ import { useSelectedVar } from '../../utils/Resolver';
21
+ import { formatNumerical, FORMATS } from '../../utils/string';
22
+ import { VirtualizedList } from '../../utils/VirtualizedList';
23
+ import { useObsData } from '../../utils/zarrData';
23
24
 
24
25
  // const N_BINS = 5;
25
26
 
@@ -40,44 +41,46 @@ import { useObsData } from "../../utils/zarrData";
40
41
  // };
41
42
  // return { ...data, bins: bins };
42
43
  // }
43
-
44
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
44
45
  function getContinuousLabel(code, binEdges) {
45
- return "[ ".concat(formatNumerical(binEdges[code][0]), ", ").concat(formatNumerical(binEdges[code][1], FORMATS.EXPONENTIAL)).concat(code === binEdges.length - 1 ? " ]" : " )");
46
+ return "[ ".concat(formatNumerical(binEdges[code][0]), ", ").concat(formatNumerical(binEdges[code][1], FORMATS.EXPONENTIAL)).concat(code === binEdges.length - 1 ? ' ]' : ' )');
46
47
  }
47
- const useObsHistogram = obs => {
48
- var _settings$selectedVar, _settings$selectedVar2, _settings$selectedVar3, _settings$selectedVar4, _settings$selectedVar9, _settings$selectedVar0, _settings$selectedVar1, _settings$selectedVar10;
49
- const ENDPOINT = "obs/histograms";
48
+ const useObsHistogram = (obs, _ref) => {
49
+ let {
50
+ enabled = true
51
+ } = _ref;
52
+ const ENDPOINT = 'obs/histograms';
50
53
  const dataset = useDataset();
51
54
  const settings = useSettings();
52
55
  const {
53
56
  obsIndices,
54
57
  isSliced
55
58
  } = useFilteredData();
59
+ const selectedVar = useSelectedVar();
56
60
  const [params, setParams] = useState({
57
61
  url: dataset.url,
58
- obsCol: _.omit(obs, "omit"),
62
+ obsCol: _.omit(obs, 'omit'),
59
63
  // avoid re-rendering when toggling unselected obs
60
- varKey: (_settings$selectedVar = settings.selectedVar) !== null && _settings$selectedVar !== void 0 && _settings$selectedVar.isSet ? {
61
- name: (_settings$selectedVar2 = settings.selectedVar) === null || _settings$selectedVar2 === void 0 ? void 0 : _settings$selectedVar2.name,
62
- indices: (_settings$selectedVar3 = settings.selectedVar) === null || _settings$selectedVar3 === void 0 ? void 0 : _settings$selectedVar3.vars.map(v => v.index)
63
- } : (_settings$selectedVar4 = settings.selectedVar) === null || _settings$selectedVar4 === void 0 ? void 0 : _settings$selectedVar4.index,
64
+ varKey: selectedVar !== null && selectedVar !== void 0 && selectedVar.isSet ? {
65
+ name: selectedVar === null || selectedVar === void 0 ? void 0 : selectedVar.name,
66
+ indices: selectedVar === null || selectedVar === void 0 ? void 0 : selectedVar.vars.map(v => v.index)
67
+ } : selectedVar === null || selectedVar === void 0 ? void 0 : selectedVar.index,
64
68
  obsIndices: isSliced ? [...(obsIndices || [])] : null
65
69
  });
66
70
  useEffect(() => {
67
71
  setParams(p => {
68
- var _settings$selectedVar5, _settings$selectedVar6, _settings$selectedVar7, _settings$selectedVar8;
69
72
  return _objectSpread(_objectSpread({}, p), {}, {
70
- obsCol: _.omit(obs, "omit"),
71
- varKey: (_settings$selectedVar5 = settings.selectedVar) !== null && _settings$selectedVar5 !== void 0 && _settings$selectedVar5.isSet ? {
72
- name: (_settings$selectedVar6 = settings.selectedVar) === null || _settings$selectedVar6 === void 0 ? void 0 : _settings$selectedVar6.name,
73
- indices: (_settings$selectedVar7 = settings.selectedVar) === null || _settings$selectedVar7 === void 0 ? void 0 : _settings$selectedVar7.vars.map(v => v.index)
74
- } : (_settings$selectedVar8 = settings.selectedVar) === null || _settings$selectedVar8 === void 0 ? void 0 : _settings$selectedVar8.index,
73
+ obsCol: _.omit(obs, 'omit'),
74
+ varKey: selectedVar !== null && selectedVar !== void 0 && selectedVar.isSet ? {
75
+ name: selectedVar === null || selectedVar === void 0 ? void 0 : selectedVar.name,
76
+ indices: selectedVar === null || selectedVar === void 0 ? void 0 : selectedVar.vars.map(v => v.index)
77
+ } : selectedVar === null || selectedVar === void 0 ? void 0 : selectedVar.index,
75
78
  obsIndices: isSliced ? [...(obsIndices || [])] : null
76
79
  });
77
80
  });
78
- }, [(_settings$selectedVar9 = settings.selectedVar) === null || _settings$selectedVar9 === void 0 ? void 0 : _settings$selectedVar9.index, (_settings$selectedVar0 = settings.selectedVar) === null || _settings$selectedVar0 === void 0 ? void 0 : _settings$selectedVar0.isSet, (_settings$selectedVar1 = settings.selectedVar) === null || _settings$selectedVar1 === void 0 ? void 0 : _settings$selectedVar1.name, (_settings$selectedVar10 = settings.selectedVar) === null || _settings$selectedVar10 === void 0 ? void 0 : _settings$selectedVar10.vars, obsIndices, isSliced, obs]);
81
+ }, [selectedVar === null || selectedVar === void 0 ? void 0 : selectedVar.index, selectedVar === null || selectedVar === void 0 ? void 0 : selectedVar.isSet, selectedVar === null || selectedVar === void 0 ? void 0 : selectedVar.name, selectedVar === null || selectedVar === void 0 ? void 0 : selectedVar.vars, obsIndices, isSliced, obs]);
79
82
  return useFetch(ENDPOINT, params, {
80
- enabled: !!settings.selectedVar && settings.colorEncoding === COLOR_ENCODINGS.VAR,
83
+ enabled: enabled && !!selectedVar && settings.colorEncoding === COLOR_ENCODINGS.VAR,
81
84
  refetchOnMount: false
82
85
  });
83
86
  };
@@ -124,7 +127,7 @@ const useFilteredObsData = obs => {
124
127
  pct: pct
125
128
  };
126
129
  };
127
- function CategoricalItem(_ref) {
130
+ function CategoricalItem(_ref2) {
128
131
  let {
129
132
  value,
130
133
  label,
@@ -147,110 +150,136 @@ function CategoricalItem(_ref) {
147
150
  pct: null
148
151
  },
149
152
  isSliced,
153
+ colors = null,
150
154
  showColor = true
151
- } = _ref;
155
+ } = _ref2;
156
+ const {
157
+ useUnsColors
158
+ } = useDataset();
152
159
  const {
153
160
  getColor
154
161
  } = useColor();
155
- return /*#__PURE__*/React.createElement("div", {
156
- className: "virtualized-list-wrapper"
157
- }, /*#__PURE__*/React.createElement(ListGroup.Item, {
158
- key: value,
159
- className: "obs-item"
160
- }, /*#__PURE__*/React.createElement("div", {
161
- className: "d-flex align-items-center"
162
- }, /*#__PURE__*/React.createElement("div", {
163
- className: "flex-grow-1"
164
- }, /*#__PURE__*/React.createElement(Form.Check, {
165
- className: "obs-value-list-check",
166
- type: "switch",
167
- label: label,
168
- checked: !isOmitted,
169
- onChange: () => onChange(value)
170
- })), /*#__PURE__*/React.createElement("div", {
171
- className: "d-flex align-items-center"
172
- }, /*#__PURE__*/React.createElement("div", {
173
- className: "pl-1 m-0 flex-grow-1"
174
- }, /*#__PURE__*/React.createElement(Histogram, {
175
- data: histogramData.data,
176
- isPending: histogramData.isPending,
177
- altColor: histogramData.altColor
178
- })), /*#__PURE__*/React.createElement("div", {
179
- className: "pl-1 m-0"
180
- }, /*#__PURE__*/React.createElement(Tooltip, {
181
- title: isSliced ? /*#__PURE__*/React.createElement(React.Fragment, null, "Filtered:", " ", formatNumerical(filteredStats.pct, FORMATS.EXPONENTIAL), "%", /*#__PURE__*/React.createElement("br", null), "Total: ", formatNumerical(stats.pct, FORMATS.EXPONENTIAL), "%") : "".concat(formatNumerical(stats.pct, FORMATS.EXPONENTIAL), "%"),
182
- placement: "left",
183
- arrow: true
184
- }, /*#__PURE__*/React.createElement("div", {
185
- className: "d-flex align-items-center"
186
- }, /*#__PURE__*/React.createElement(Badge, {
187
- className: "value-count-badge"
188
- }, " ", isSliced && /*#__PURE__*/React.createElement(React.Fragment, null, formatNumerical(parseInt(filteredStats.value_counts)), " ", "out of", " "), formatNumerical(parseInt(stats.value_counts), FORMATS.EXPONENTIAL)), /*#__PURE__*/React.createElement("div", {
189
- className: "value-pct-gauge-container"
190
- }, isSliced ? /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Gauge, {
191
- className: "pct-gauge filtered-pct-gauge",
192
- value: filteredStats.pct,
193
- text: null,
194
- innerRadius: "50%",
195
- outerRadius: "75%",
196
- margin: {
197
- top: 0,
198
- right: 0,
199
- bottom: 0,
200
- left: 0
201
- }
202
- }), /*#__PURE__*/React.createElement(Gauge, {
203
- className: "pct-gauge",
204
- value: stats.pct,
205
- text: null,
206
- innerRadius: "75%",
207
- margin: {
208
- top: 0,
209
- right: 0,
210
- bottom: 0,
211
- left: 0
212
- }
213
- })) : /*#__PURE__*/React.createElement(Gauge, {
214
- value: stats.pct,
215
- text: null,
216
- innerRadius: "50%",
217
- margin: {
218
- top: 0,
219
- right: 0,
220
- bottom: 0,
221
- left: 0
222
- }
223
- }))))), showColor ? /*#__PURE__*/React.createElement("div", {
224
- className: "pl-1"
225
- }, /*#__PURE__*/React.createElement("svg", {
226
- xmlns: "http://www.w3.org/2000/svg",
227
- width: 24,
228
- height: 24,
229
- fill: "currentColor",
230
- viewBox: "0 0 10 10"
231
- }, /*#__PURE__*/React.createElement("rect", {
232
- x: "0",
233
- y: "0",
234
- width: "10",
235
- height: "10",
236
- fill: "rgb(".concat(getColor({
237
- value: (code - min) / (max - min),
238
- categorical: true,
239
- grayOut: isOmitted,
240
- grayParams: {
241
- alpha: 1
242
- },
243
- colorEncoding: "obs"
244
- }), ")")
245
- }))) : null))));
162
+ return /*#__PURE__*/_jsx("div", {
163
+ className: "virtualized-list-wrapper",
164
+ children: /*#__PURE__*/_jsx(ListGroup.Item, {
165
+ className: "obs-item",
166
+ children: /*#__PURE__*/_jsxs("div", {
167
+ className: "d-flex align-items-center flex-wrap",
168
+ children: [/*#__PURE__*/_jsx("div", {
169
+ className: "flex-grow-1 me-auto mw-100",
170
+ children: /*#__PURE__*/_jsx(Form.Check, {
171
+ className: "obs-value-list-check",
172
+ type: "switch",
173
+ title: label,
174
+ label: label,
175
+ checked: !isOmitted,
176
+ onChange: () => onChange(value)
177
+ })
178
+ }), /*#__PURE__*/_jsxs("div", {
179
+ className: "d-flex align-items-center ms-auto",
180
+ children: [(!!histogramData.data || histogramData.isPending) && /*#__PURE__*/_jsx("div", {
181
+ className: "pl-1 m-0",
182
+ children: /*#__PURE__*/_jsx(Histogram, {
183
+ data: histogramData.data,
184
+ isPending: histogramData.isPending,
185
+ altColor: histogramData.altColor
186
+ })
187
+ }), /*#__PURE__*/_jsx("div", {
188
+ className: "pl-1 m-0",
189
+ children: /*#__PURE__*/_jsx(Tooltip, {
190
+ title: isSliced ? /*#__PURE__*/_jsxs(_Fragment, {
191
+ children: ["Filtered:", ' ', formatNumerical(filteredStats.pct, FORMATS.EXPONENTIAL), "%", /*#__PURE__*/_jsx("br", {}), "Total: ", formatNumerical(stats.pct, FORMATS.EXPONENTIAL), "%"]
192
+ }) : "".concat(formatNumerical(stats.pct, FORMATS.EXPONENTIAL), "%"),
193
+ placement: "left",
194
+ arrow: true,
195
+ children: /*#__PURE__*/_jsxs("div", {
196
+ className: "d-flex align-items-center",
197
+ children: [/*#__PURE__*/_jsxs(Badge, {
198
+ className: "value-count-badge",
199
+ children: [' ', isSliced && parseInt(filteredStats.value_counts) !== parseInt(stats.value_counts) && /*#__PURE__*/_jsxs(_Fragment, {
200
+ children: [formatNumerical(parseInt(filteredStats.value_counts)), ' ', "out of", ' ']
201
+ }), formatNumerical(parseInt(stats.value_counts), FORMATS.EXPONENTIAL)]
202
+ }), /*#__PURE__*/_jsx("div", {
203
+ className: "value-pct-gauge-container",
204
+ children: isSliced ? /*#__PURE__*/_jsxs(_Fragment, {
205
+ children: [/*#__PURE__*/_jsx(Gauge, {
206
+ className: "pct-gauge filtered-pct-gauge",
207
+ value: filteredStats.pct,
208
+ text: null,
209
+ innerRadius: '50%',
210
+ outerRadius: '75%',
211
+ margin: {
212
+ top: 0,
213
+ right: 0,
214
+ bottom: 0,
215
+ left: 0
216
+ }
217
+ }), /*#__PURE__*/_jsx(Gauge, {
218
+ className: "pct-gauge",
219
+ value: stats.pct,
220
+ text: null,
221
+ innerRadius: '75%',
222
+ margin: {
223
+ top: 0,
224
+ right: 0,
225
+ bottom: 0,
226
+ left: 0
227
+ }
228
+ })]
229
+ }) : /*#__PURE__*/_jsx(Gauge, {
230
+ value: stats.pct,
231
+ text: null,
232
+ innerRadius: '50%',
233
+ margin: {
234
+ top: 0,
235
+ right: 0,
236
+ bottom: 0,
237
+ left: 0
238
+ }
239
+ })
240
+ })]
241
+ })
242
+ })
243
+ }), showColor ? /*#__PURE__*/_jsx("div", {
244
+ className: "pl-1",
245
+ children: /*#__PURE__*/_jsx("svg", {
246
+ xmlns: "http://www.w3.org/2000/svg",
247
+ width: 24,
248
+ height: 24,
249
+ fill: "currentColor",
250
+ viewBox: "0 0 10 10",
251
+ children: /*#__PURE__*/_jsx("rect", {
252
+ x: "0",
253
+ y: "0",
254
+ width: "10",
255
+ height: "10",
256
+ fill: "rgb(".concat(getColor(_objectSpread({
257
+ value: (code - min) / (max - min),
258
+ categorical: true,
259
+ grayOut: isOmitted,
260
+ grayParams: {
261
+ alpha: 1
262
+ },
263
+ colorEncoding: 'obs'
264
+ }, useUnsColors ? {
265
+ colorscale: colors
266
+ } : {})), ")")
267
+ })
268
+ })
269
+ }) : null]
270
+ })]
271
+ })
272
+ }, value)
273
+ });
246
274
  }
247
- export function CategoricalObs(_ref2) {
275
+ export function CategoricalObs(_ref3) {
248
276
  let {
249
277
  obs,
250
278
  toggleAll,
251
279
  toggleObs,
252
- showColor = true
253
- } = _ref2;
280
+ showColor = true,
281
+ showHistograms = true
282
+ } = _ref3;
254
283
  const settings = useSettings();
255
284
  const {
256
285
  isSliced
@@ -258,8 +287,11 @@ export function CategoricalObs(_ref2) {
258
287
  const totalCounts = _.sum(_.values(obs.value_counts));
259
288
  const min = _.min(_.values(obs.codes));
260
289
  const max = _.max(_.values(obs.codes));
261
- const obsHistograms = useObsHistogram(obs);
290
+ const obsHistograms = useObsHistogram(obs, {
291
+ enabled: showHistograms
292
+ });
262
293
  const filteredObsData = useFilteredObsData(obs);
294
+ const enabledHistograms = useMemo(() => showHistograms && settings.colorEncoding === COLOR_ENCODINGS.VAR, [settings.colorEncoding, showHistograms]);
263
295
  const getDataAtIndex = useCallback(index => {
264
296
  var _obsHistograms$fetche;
265
297
  return {
@@ -269,9 +301,9 @@ export function CategoricalObs(_ref2) {
269
301
  value_counts: obs.value_counts[obs.values[index]],
270
302
  pct: obs.value_counts[obs.values[index]] / totalCounts * 100
271
303
  },
272
- isOmitted: _.includes(obs.omit, obs.codes[obs.values[index]]),
304
+ isOmitted: _.includes(obs.omit, obs.values[index]),
273
305
  label: obs.values[index],
274
- histogramData: settings.colorEncoding === COLOR_ENCODINGS.VAR ? {
306
+ histogramData: enabledHistograms ? {
275
307
  data: (_obsHistograms$fetche = obsHistograms.fetchedData) === null || _obsHistograms$fetche === void 0 ? void 0 : _obsHistograms$fetche[obs.values[index]],
276
308
  isPending: obsHistograms.isPending,
277
309
  altColor: isSliced
@@ -283,35 +315,42 @@ export function CategoricalObs(_ref2) {
283
315
  value_counts: (filteredObsData === null || filteredObsData === void 0 ? void 0 : filteredObsData.value_counts[obs.values[index]]) || 0,
284
316
  pct: (filteredObsData === null || filteredObsData === void 0 ? void 0 : filteredObsData.pct[obs.values[index]]) || 0
285
317
  },
286
- isSliced: isSliced
318
+ isSliced: isSliced,
319
+ colors: obs.colors
287
320
  };
288
- }, [settings.colorEncoding, filteredObsData === null || filteredObsData === void 0 ? void 0 : filteredObsData.pct, filteredObsData === null || filteredObsData === void 0 ? void 0 : filteredObsData.value_counts, isSliced, obs.codes, obs.omit, obs.value_counts, obs.values, obsHistograms.fetchedData, obsHistograms.isPending, totalCounts]);
321
+ }, [obs.values, obs.codes, obs.value_counts, obs.omit, obs.colors, totalCounts, enabledHistograms, obsHistograms.fetchedData, obsHistograms.isPending, isSliced, filteredObsData === null || filteredObsData === void 0 ? void 0 : filteredObsData.value_counts, filteredObsData === null || filteredObsData === void 0 ? void 0 : filteredObsData.pct]);
289
322
  showColor &= settings.colorEncoding === COLOR_ENCODINGS.OBS;
290
- return /*#__PURE__*/React.createElement(ListGroup, {
323
+ return /*#__PURE__*/_jsxs(ListGroup, {
291
324
  variant: "flush",
292
- className: "cherita-list"
293
- }, /*#__PURE__*/React.createElement(ListGroup.Item, {
294
- className: "unstyled"
295
- }, /*#__PURE__*/React.createElement(ObsToolbar, {
296
- item: obs,
297
- onToggleAllObs: toggleAll
298
- })), /*#__PURE__*/React.createElement(VirtualizedList, {
299
- getDataAtIndex: getDataAtIndex,
300
- count: obs.values.length,
301
- ItemComponent: CategoricalItem,
302
- totalCounts: totalCounts,
303
- min: min,
304
- max: max,
305
- onChange: toggleObs,
306
- showColor: showColor,
307
- estimateSize: 42
308
- }));
325
+ className: "cherita-list",
326
+ children: [/*#__PURE__*/_jsx(ListGroup.Item, {
327
+ className: "unstyled",
328
+ children: /*#__PURE__*/_jsx(ObsToolbar, {
329
+ item: obs,
330
+ onToggleAllObs: toggleAll
331
+ })
332
+ }), /*#__PURE__*/_jsx(VirtualizedList, {
333
+ getDataAtIndex: getDataAtIndex,
334
+ count: obs.values.length,
335
+ ItemComponent: CategoricalItem,
336
+ totalCounts: totalCounts,
337
+ min: min,
338
+ max: max,
339
+ onChange: toggleObs,
340
+ showColor: showColor,
341
+ estimateSize: i =>
342
+ // rough attempt to determine size based on label length
343
+ // estimate size of 68 pixels if label is long (>=25 chars if enabledHistograms, >=30 if showColor, >=35 otherwise), else 42
344
+ // TODO: consider isSliced as count badge will be longer ?
345
+ obs.values[i].length >= (enabledHistograms ? 25 : showColor ? 30 : 35) ? 68 : 42
346
+ })]
347
+ });
309
348
  }
310
- function ObsContinuousStats(_ref3) {
349
+ function ObsContinuousStats(_ref4) {
311
350
  let {
312
351
  obs
313
- } = _ref3;
314
- const ENDPOINT = "obs/distribution";
352
+ } = _ref4;
353
+ const ENDPOINT = 'obs/distribution';
315
354
  const dataset = useDataset();
316
355
  const params = {
317
356
  url: dataset.url,
@@ -324,67 +363,103 @@ function ObsContinuousStats(_ref3) {
324
363
  } = useFetch(ENDPOINT, params);
325
364
 
326
365
  // @TODO: fix width issue when min/max/etc values are too large
327
- return /*#__PURE__*/React.createElement("div", {
328
- className: "obs-statistics"
329
- }, /*#__PURE__*/React.createElement("h5", {
330
- className: "mb-2"
331
- }, "Statistics"), /*#__PURE__*/React.createElement("div", {
332
- className: "row"
333
- }, /*#__PURE__*/React.createElement("div", {
334
- className: "col-md-7"
335
- }, /*#__PURE__*/React.createElement("p", {
336
- className: "mb-1 small"
337
- }, "Distribution of continuous values"), isPending && /*#__PURE__*/React.createElement(LoadingLinear, null), !isPending && !serverError && /*#__PURE__*/React.createElement("div", {
338
- className: "obs-distribution"
339
- }, /*#__PURE__*/React.createElement(SparkLineChart, {
340
- data: fetchedData.kde_values[1],
341
- showHighlight: true,
342
- showTooltip: true,
343
- margin: {
344
- top: 10,
345
- right: 20,
346
- bottom: 10,
347
- left: 20
348
- },
349
- xAxis: {
350
- data: fetchedData.kde_values[0],
351
- valueFormatter: v => "".concat(formatNumerical(v, FORMATS.EXPONENTIAL))
352
- },
353
- valueFormatter: v => "".concat(formatNumerical(v, FORMATS.EXPONENTIAL)),
354
- slotProps: {
355
- popper: {
356
- className: "feature-histogram-tooltip"
357
- }
358
- }
359
- }))), /*#__PURE__*/React.createElement("div", {
360
- className: "col-md-5 d-flex flex-column text-end"
361
- }, /*#__PURE__*/React.createElement("div", {
362
- className: "d-flex justify-content-between"
363
- }, /*#__PURE__*/React.createElement("span", null, "Min"), " ", /*#__PURE__*/React.createElement("span", null, formatNumerical(obs.min, FORMATS.EXPONENTIAL))), /*#__PURE__*/React.createElement("div", {
364
- className: "d-flex justify-content-between"
365
- }, /*#__PURE__*/React.createElement("span", null, "Max"), " ", /*#__PURE__*/React.createElement("span", null, formatNumerical(obs.max, FORMATS.EXPONENTIAL))), /*#__PURE__*/React.createElement("div", {
366
- className: "d-flex justify-content-between"
367
- }, /*#__PURE__*/React.createElement("span", null, "Mean"), " ", /*#__PURE__*/React.createElement("span", null, formatNumerical(obs.mean, FORMATS.EXPONENTIAL))), /*#__PURE__*/React.createElement("div", {
368
- className: "d-flex justify-content-between"
369
- }, /*#__PURE__*/React.createElement("span", null, "Median"), " ", /*#__PURE__*/React.createElement("span", null, formatNumerical(obs.median, FORMATS.EXPONENTIAL))))));
366
+ return /*#__PURE__*/_jsxs("div", {
367
+ className: "obs-statistics",
368
+ children: [/*#__PURE__*/_jsx("h5", {
369
+ className: "mb-2",
370
+ children: "Statistics"
371
+ }), /*#__PURE__*/_jsxs("div", {
372
+ className: "row",
373
+ children: [/*#__PURE__*/_jsxs("div", {
374
+ className: "col-md-7",
375
+ children: [/*#__PURE__*/_jsx("p", {
376
+ className: "mb-1 small",
377
+ children: "Distribution of continuous values"
378
+ }), isPending && /*#__PURE__*/_jsx(LoadingLinear, {}), !isPending && !serverError && /*#__PURE__*/_jsx("div", {
379
+ className: "obs-distribution",
380
+ children: /*#__PURE__*/_jsx(SparkLineChart, {
381
+ data: fetchedData.kde_values[1],
382
+ showHighlight: true,
383
+ showTooltip: true,
384
+ margin: {
385
+ top: 10,
386
+ right: 20,
387
+ bottom: 10,
388
+ left: 20
389
+ },
390
+ xAxis: {
391
+ data: fetchedData.kde_values[0],
392
+ valueFormatter: v => "".concat(formatNumerical(v, FORMATS.EXPONENTIAL))
393
+ },
394
+ valueFormatter: v => "".concat(formatNumerical(v, FORMATS.EXPONENTIAL)),
395
+ slotProps: {
396
+ popper: {
397
+ className: 'feature-histogram-tooltip'
398
+ }
399
+ }
400
+ })
401
+ })]
402
+ }), /*#__PURE__*/_jsxs("div", {
403
+ className: "col-md-5 d-flex flex-column text-end",
404
+ children: [/*#__PURE__*/_jsxs("div", {
405
+ className: "d-flex justify-content-between",
406
+ children: [/*#__PURE__*/_jsx("span", {
407
+ children: "Min"
408
+ }), ' ', /*#__PURE__*/_jsx("span", {
409
+ children: formatNumerical(obs.min, FORMATS.EXPONENTIAL)
410
+ })]
411
+ }), /*#__PURE__*/_jsxs("div", {
412
+ className: "d-flex justify-content-between",
413
+ children: [/*#__PURE__*/_jsx("span", {
414
+ children: "Max"
415
+ }), ' ', /*#__PURE__*/_jsx("span", {
416
+ children: formatNumerical(obs.max, FORMATS.EXPONENTIAL)
417
+ })]
418
+ }), /*#__PURE__*/_jsxs("div", {
419
+ className: "d-flex justify-content-between",
420
+ children: [/*#__PURE__*/_jsx("span", {
421
+ children: "Mean"
422
+ }), ' ', /*#__PURE__*/_jsx("span", {
423
+ children: formatNumerical(obs.mean, FORMATS.EXPONENTIAL)
424
+ })]
425
+ }), /*#__PURE__*/_jsxs("div", {
426
+ className: "d-flex justify-content-between",
427
+ children: [/*#__PURE__*/_jsx("span", {
428
+ children: "Median"
429
+ }), ' ', /*#__PURE__*/_jsx("span", {
430
+ children: formatNumerical(obs.median, FORMATS.EXPONENTIAL)
431
+ })]
432
+ })]
433
+ })]
434
+ })]
435
+ });
370
436
  }
371
437
 
372
438
  // @TODO: add bin controls
373
- // @TODO: add histogram
374
- export function ContinuousObs(_ref4) {
439
+ export function ContinuousObs(_ref5) {
375
440
  let {
376
441
  obs,
377
442
  toggleAll,
378
- toggleObs
379
- } = _ref4;
443
+ toggleObs,
444
+ showHistograms = true
445
+ } = _ref5;
446
+ const settings = useSettings();
380
447
  const {
381
448
  isSliced
382
449
  } = useFilteredData();
383
450
  const totalCounts = _.sum(_.values(obs.value_counts));
384
451
  const min = _.min(_.values(obs.codes));
385
452
  const max = _.max(_.values(obs.codes));
453
+ const obsHistograms = useObsHistogram(obs, {
454
+ enabled: showHistograms
455
+ });
386
456
  const filteredObsData = useFilteredObsData(obs);
387
- const getDataAtIndex = index => {
457
+ const enabledHistograms = useMemo(() => showHistograms && settings.colorEncoding === COLOR_ENCODINGS.VAR, [settings.colorEncoding, showHistograms]);
458
+ const getLabel = useCallback(index => {
459
+ return isNaN(obs.values[index]) ? 'NaN' : getContinuousLabel(obs.codes[obs.values[index]], obs.bins.binEdges);
460
+ }, [obs.bins.binEdges, obs.codes, obs.values]);
461
+ const getDataAtIndex = useCallback(index => {
462
+ var _obsHistograms$fetche2;
388
463
  return {
389
464
  value: obs.values[index],
390
465
  code: obs.codes[obs.values[index]],
@@ -392,33 +467,50 @@ export function ContinuousObs(_ref4) {
392
467
  value_counts: obs.value_counts[obs.values[index]],
393
468
  pct: obs.value_counts[obs.values[index]] / totalCounts * 100
394
469
  },
395
- isOmitted: _.includes(obs.omit, obs.codes[obs.values[index]]),
396
- label: isNaN(obs.values[index]) ? "NaN" : getContinuousLabel(obs.codes[obs.values[index]], obs.bins.binEdges),
470
+ isOmitted: _.includes(obs.omit, obs.values[index]),
471
+ label: getLabel(index),
472
+ histogramData: enabledHistograms ? {
473
+ data: (_obsHistograms$fetche2 = obsHistograms.fetchedData) === null || _obsHistograms$fetche2 === void 0 ? void 0 : _obsHistograms$fetche2[obs.values[index]],
474
+ isPending: obsHistograms.isPending,
475
+ altColor: isSliced
476
+ } : {
477
+ data: null,
478
+ isPending: false
479
+ },
397
480
  filteredStats: {
398
481
  value_counts: (filteredObsData === null || filteredObsData === void 0 ? void 0 : filteredObsData.value_counts[obs.values[index]]) || 0,
399
482
  pct: (filteredObsData === null || filteredObsData === void 0 ? void 0 : filteredObsData.pct[obs.values[index]]) || 0
400
483
  },
401
484
  isSliced: isSliced
402
485
  };
403
- };
404
- return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(ListGroup, {
405
- variant: "flush",
406
- className: "cherita-list"
407
- }, /*#__PURE__*/React.createElement(ListGroup.Item, {
408
- className: "unstyled"
409
- }, /*#__PURE__*/React.createElement(ObsToolbar, {
410
- item: obs,
411
- onToggleAllObs: toggleAll
412
- })), /*#__PURE__*/React.createElement(VirtualizedList, {
413
- getDataAtIndex: getDataAtIndex,
414
- count: obs.values.length,
415
- ItemComponent: CategoricalItem,
416
- totalCounts: totalCounts,
417
- min: min,
418
- max: max,
419
- onChange: toggleObs,
420
- showColor: false
421
- })), /*#__PURE__*/React.createElement(ObsContinuousStats, {
422
- obs: obs
423
- }));
486
+ }, [enabledHistograms, filteredObsData === null || filteredObsData === void 0 ? void 0 : filteredObsData.pct, filteredObsData === null || filteredObsData === void 0 ? void 0 : filteredObsData.value_counts, getLabel, isSliced, obs.codes, obs.omit, obs.value_counts, obs.values, obsHistograms.fetchedData, obsHistograms.isPending, totalCounts]);
487
+ return /*#__PURE__*/_jsxs(_Fragment, {
488
+ children: [/*#__PURE__*/_jsxs(ListGroup, {
489
+ variant: "flush",
490
+ className: "cherita-list",
491
+ children: [/*#__PURE__*/_jsx(ListGroup.Item, {
492
+ className: "unstyled",
493
+ children: /*#__PURE__*/_jsx(ObsToolbar, {
494
+ item: obs,
495
+ onToggleAllObs: toggleAll
496
+ })
497
+ }), /*#__PURE__*/_jsx(VirtualizedList, {
498
+ getDataAtIndex: getDataAtIndex,
499
+ count: obs.values.length,
500
+ ItemComponent: CategoricalItem,
501
+ totalCounts: totalCounts,
502
+ min: min,
503
+ max: max,
504
+ onChange: toggleObs,
505
+ showColor: false,
506
+ estimateSize: i =>
507
+ // rough attempt to determine size based on label length
508
+ // estimate size of 68 pixels if label is long (>=20 chars if enabledHistograms, >=30 otherwise), else 42
509
+ // TODO: consider isSliced as count badge will be longer ?
510
+ getLabel(i).length >= (enabledHistograms ? 20 : 30) ? 68 : 42
511
+ })]
512
+ }), /*#__PURE__*/_jsx(ObsContinuousStats, {
513
+ obs: obs
514
+ })]
515
+ });
424
516
  }