@haniffalab/cherita-react 1.0.0 → 1.1.0

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 (106) hide show
  1. package/LICENSE +1 -1
  2. package/dist/{components → cjs/components}/full-page/FullPage.js +32 -22
  3. package/dist/{components → cjs/components}/full-page/FullPagePseudospatial.js +7 -6
  4. package/dist/{components → cjs/components}/obs-list/ObsItem.js +88 -77
  5. package/dist/{components → cjs/components}/obs-list/ObsList.js +133 -50
  6. package/dist/cjs/components/obs-list/ObsToolbar.js +24 -0
  7. package/dist/{components → cjs/components}/obsm-list/ObsmList.js +8 -5
  8. package/dist/{components → cjs/components}/offcanvas/index.js +24 -20
  9. package/dist/{components → cjs/components}/pseudospatial/Pseudospatial.js +10 -9
  10. package/dist/{components → cjs/components}/pseudospatial/PseudospatialToolbar.js +4 -3
  11. package/dist/{components → cjs/components}/scatterplot/Scatterplot.js +33 -24
  12. package/dist/{components → cjs/components}/scatterplot/SpatialControls.js +43 -42
  13. package/dist/cjs/components/scatterplot/Toolbox.js +62 -0
  14. package/dist/{components → cjs/components}/search-bar/SearchBar.js +24 -7
  15. package/dist/{components → cjs/components}/search-bar/SearchResults.js +13 -17
  16. package/dist/{components → cjs/components}/var-list/VarItem.js +38 -29
  17. package/dist/{components → cjs/components}/var-list/VarList.js +59 -31
  18. package/dist/{components → cjs/components}/var-list/VarListToolbar.js +18 -14
  19. package/dist/{components → cjs/components}/var-list/VarSet.js +24 -20
  20. package/dist/{components → cjs/components}/violin/Violin.js +4 -3
  21. package/dist/{constants → cjs/constants}/constants.js +6 -2
  22. package/dist/{context → cjs/context}/DatasetContext.js +12 -11
  23. package/dist/{context → cjs/context}/FilterContext.js +4 -3
  24. package/dist/{context → cjs/context}/ZarrDataContext.js +4 -3
  25. package/dist/{helpers → cjs/helpers}/color-helper.js +12 -11
  26. package/dist/{helpers → cjs/helpers}/map-helper.js +8 -7
  27. package/dist/{helpers → cjs/helpers}/zarr-helper.js +30 -38
  28. package/dist/{utils → cjs/utils}/Filter.js +1 -1
  29. package/dist/{utils → cjs/utils}/Histogram.js +12 -8
  30. package/dist/{utils → cjs/utils}/ImageViewer.js +6 -5
  31. package/dist/{utils → cjs/utils}/Legend.js +8 -7
  32. package/dist/{utils → cjs/utils}/LoadingIndicators.js +5 -4
  33. package/dist/cjs/utils/Skeleton.js +19 -0
  34. package/dist/{utils → cjs/utils}/VirtualizedList.js +10 -9
  35. package/dist/{utils → cjs/utils}/requests.js +37 -39
  36. package/dist/{utils → cjs/utils}/string.js +9 -4
  37. package/dist/{utils → cjs/utils}/zarrData.js +12 -4
  38. package/dist/css/cherita.css +147 -152
  39. package/dist/css/cherita.css.map +1 -1
  40. package/dist/esm/components/dotplot/Dotplot.js +135 -0
  41. package/dist/esm/components/dotplot/DotplotControls.js +148 -0
  42. package/dist/esm/components/full-page/FullPage.js +143 -0
  43. package/dist/esm/components/full-page/FullPagePseudospatial.js +151 -0
  44. package/dist/esm/components/heatmap/Heatmap.js +105 -0
  45. package/dist/esm/components/heatmap/HeatmapControls.js +23 -0
  46. package/dist/esm/components/matrixplot/Matrixplot.js +107 -0
  47. package/dist/esm/components/matrixplot/MatrixplotControls.js +38 -0
  48. package/dist/esm/components/obs-list/ObsItem.js +484 -0
  49. package/dist/esm/components/obs-list/ObsList.js +338 -0
  50. package/dist/esm/components/obs-list/ObsToolbar.js +17 -0
  51. package/dist/esm/components/obsm-list/ObsmList.js +75 -0
  52. package/dist/esm/components/offcanvas/index.js +67 -0
  53. package/dist/esm/components/pseudospatial/Pseudospatial.js +228 -0
  54. package/dist/esm/components/pseudospatial/PseudospatialToolbar.js +123 -0
  55. package/dist/esm/components/scatterplot/Scatterplot.js +394 -0
  56. package/dist/esm/components/scatterplot/ScatterplotControls.js +71 -0
  57. package/dist/esm/components/scatterplot/SpatialControls.js +140 -0
  58. package/dist/esm/components/scatterplot/Toolbox.js +55 -0
  59. package/dist/esm/components/search-bar/SearchBar.js +90 -0
  60. package/dist/esm/components/search-bar/SearchResults.js +139 -0
  61. package/dist/esm/components/var-list/VarItem.js +254 -0
  62. package/dist/esm/components/var-list/VarList.js +291 -0
  63. package/dist/esm/components/var-list/VarListToolbar.js +87 -0
  64. package/dist/esm/components/var-list/VarSet.js +194 -0
  65. package/dist/esm/components/violin/Violin.js +141 -0
  66. package/dist/esm/components/violin/ViolinControls.js +24 -0
  67. package/dist/esm/constants/colorscales.js +22 -0
  68. package/dist/esm/constants/constants.js +88 -0
  69. package/dist/esm/context/DatasetContext.js +571 -0
  70. package/dist/esm/context/FilterContext.js +48 -0
  71. package/dist/esm/context/ZarrDataContext.js +26 -0
  72. package/dist/esm/helpers/color-helper.js +66 -0
  73. package/dist/esm/helpers/map-helper.js +53 -0
  74. package/dist/esm/helpers/zarr-helper.js +111 -0
  75. package/dist/esm/index.js +22 -0
  76. package/dist/esm/utils/Filter.js +147 -0
  77. package/dist/esm/utils/Histogram.js +44 -0
  78. package/dist/esm/utils/ImageViewer.js +27 -0
  79. package/dist/esm/utils/Legend.js +58 -0
  80. package/dist/esm/utils/LoadingIndicators.js +22 -0
  81. package/dist/esm/utils/Skeleton.js +12 -0
  82. package/dist/esm/utils/VirtualizedList.js +55 -0
  83. package/dist/esm/utils/errors.js +47 -0
  84. package/dist/esm/utils/requests.js +102 -0
  85. package/dist/esm/utils/search.js +39 -0
  86. package/dist/esm/utils/string.js +59 -0
  87. package/dist/esm/utils/zarrData.js +102 -0
  88. package/package.json +19 -7
  89. package/scss/cherita.scss +19 -50
  90. package/scss/components/accordions.scss +32 -0
  91. package/scss/components/layouts.scss +2 -1
  92. package/scss/components/lists.scss +14 -0
  93. package/dist/components/obs-list/ObsToolbar.js +0 -64
  94. package/dist/components/scatterplot/Toolbox.js +0 -31
  95. /package/dist/{components → cjs/components}/dotplot/Dotplot.js +0 -0
  96. /package/dist/{components → cjs/components}/dotplot/DotplotControls.js +0 -0
  97. /package/dist/{components → cjs/components}/heatmap/Heatmap.js +0 -0
  98. /package/dist/{components → cjs/components}/heatmap/HeatmapControls.js +0 -0
  99. /package/dist/{components → cjs/components}/matrixplot/Matrixplot.js +0 -0
  100. /package/dist/{components → cjs/components}/matrixplot/MatrixplotControls.js +0 -0
  101. /package/dist/{components → cjs/components}/scatterplot/ScatterplotControls.js +0 -0
  102. /package/dist/{components → cjs/components}/violin/ViolinControls.js +0 -0
  103. /package/dist/{constants → cjs/constants}/colorscales.js +0 -0
  104. /package/dist/{index.js → cjs/index.js} +0 -0
  105. /package/dist/{utils → cjs/utils}/errors.js +0 -0
  106. /package/dist/{utils → cjs/utils}/search.js +0 -0
@@ -0,0 +1,228 @@
1
+ import React, { useCallback, useEffect, useMemo, useRef, useState } from "react";
2
+ import { library } from "@fortawesome/fontawesome-svg-core";
3
+ import { faSliders } from "@fortawesome/free-solid-svg-icons";
4
+ import _ from "lodash";
5
+ import { Alert } from "react-bootstrap";
6
+ import Plot from "react-plotly.js";
7
+ import { COLOR_ENCODINGS, OBS_TYPES, PSEUDOSPATIAL_PLOT_TYPES as PLOT_TYPES } from "../../constants/constants";
8
+ import { useDataset } from "../../context/DatasetContext";
9
+ import { useFilteredData } from "../../context/FilterContext";
10
+ import { rgbToHex, useColor } from "../../helpers/color-helper";
11
+ import { ImageViewer } from "../../utils/ImageViewer";
12
+ import { Legend } from "../../utils/Legend";
13
+ import { LoadingSpinner } from "../../utils/LoadingIndicators";
14
+ import { useDebouncedFetch } from "../../utils/requests";
15
+ library.add(faSliders);
16
+ function usePseudospatialData(plotType) {
17
+ const ENDPOINT = "pseudospatial";
18
+ const dataset = useDataset();
19
+ const {
20
+ obsIndices,
21
+ isSliced
22
+ } = useFilteredData();
23
+ const baseParams = useMemo(() => {
24
+ return {
25
+ url: dataset.url,
26
+ maskSet: dataset.pseudospatial.maskSet,
27
+ maskValues: dataset.pseudospatial.maskValues,
28
+ obsIndices: isSliced ? [...(obsIndices || [])] : null,
29
+ varNamesCol: dataset.varNamesCol,
30
+ showColorbar: false,
31
+ format: "json"
32
+ };
33
+ }, [dataset.url, dataset.pseudospatial.maskSet, dataset.pseudospatial.maskValues, dataset.varNamesCol, isSliced, obsIndices]);
34
+ const getPlotParams = useCallback(() => {
35
+ if (plotType === PLOT_TYPES.GENE) {
36
+ return {
37
+ varKey: dataset.selectedVar?.isSet ? {
38
+ name: dataset.selectedVar?.name,
39
+ indices: dataset.selectedVar?.vars.map(v => v.index)
40
+ } : dataset.selectedVar?.index,
41
+ ...(dataset.sliceBy.obs ? {
42
+ obsCol: dataset.selectedObs,
43
+ obsValues: !dataset.selectedObs?.omit.length ? null : _.difference(_.values(dataset.selectedObs?.codes), dataset.selectedObs?.omit).map(c => dataset.selectedObs?.codesMap[c])
44
+ } : {})
45
+ };
46
+ } else if (plotType === PLOT_TYPES.CATEGORICAL) {
47
+ return {
48
+ obsCol: dataset.selectedObs,
49
+ obsValues: !dataset.selectedObs?.omit.length ? null : _.difference(_.values(dataset.selectedObs?.codes), dataset.selectedObs?.omit).map(c => dataset.selectedObs?.codesMap[c]),
50
+ mode: dataset.pseudospatial.categoricalMode
51
+ };
52
+ } else if (plotType === "continuous") {
53
+ return {
54
+ obsCol: dataset.selectedObs,
55
+ obsValues: !dataset.selectedObs?.omit.length ? null : _.difference(_.values(dataset.selectedObs?.codes), dataset.selectedObs?.omit).map(c => dataset.selectedObs?.codesMap[c])
56
+ };
57
+ }
58
+ }, [dataset.pseudospatial.categoricalMode, dataset.selectedObs, dataset.selectedVar?.index, dataset.selectedVar?.isSet, dataset.selectedVar?.name, dataset.selectedVar?.vars, dataset.sliceBy.obs, plotType]);
59
+ const params = useMemo(() => {
60
+ return {
61
+ ...baseParams,
62
+ ...getPlotParams()
63
+ };
64
+ }, [baseParams, getPlotParams]);
65
+ return useDebouncedFetch(ENDPOINT + "/" + plotType, params, 500, {
66
+ enabled: !!plotType && !!dataset.pseudospatial.maskSet
67
+ });
68
+ }
69
+ export function Pseudospatial(_ref) {
70
+ let {
71
+ showLegend = true,
72
+ sharedScaleRange = false,
73
+ height = 200,
74
+ setShowControls,
75
+ plotType,
76
+ setPlotType
77
+ } = _ref;
78
+ const dataset = useDataset();
79
+ const [data, setData] = useState([]);
80
+ const [layout, setLayout] = useState({});
81
+ const {
82
+ getColor
83
+ } = useColor();
84
+ const colorscale = useRef(dataset.controls.colorScale);
85
+ useEffect(() => {
86
+ setPlotType(dataset.colorEncoding === COLOR_ENCODINGS.VAR ? PLOT_TYPES.GENE : dataset.selectedObs?.type === OBS_TYPES.CATEGORICAL || dataset.selectedObs?.type === OBS_TYPES.BOOLEAN ? PLOT_TYPES.CATEGORICAL : dataset.selectedObs?.type === OBS_TYPES.CONTINUOUS ? PLOT_TYPES.CONTINUOUS : PLOT_TYPES.MASKS);
87
+ }, [dataset.colorEncoding, dataset.selectedObs?.type, setPlotType]);
88
+ const updateColorscale = useCallback(colorscale => {
89
+ setLayout(l => {
90
+ return {
91
+ ...l,
92
+ coloraxis: {
93
+ ...l.coloraxis,
94
+ colorscale: colorscale
95
+ }
96
+ };
97
+ });
98
+ setData(d => {
99
+ const min = layout?.coloraxis?.cmin;
100
+ const max = layout?.coloraxis?.cmax;
101
+ return _.map(d, trace => {
102
+ const v = trace.meta.value;
103
+ if (v === null) {
104
+ return trace;
105
+ }
106
+ const color = rgbToHex(getColor({
107
+ value: (v - min) / (max - min)
108
+ }));
109
+ return {
110
+ ...trace,
111
+ fillcolor: color,
112
+ line: {
113
+ ...trace.line,
114
+ color: color
115
+ }
116
+ };
117
+ });
118
+ });
119
+ }, [getColor, layout?.coloraxis?.cmax, layout?.coloraxis?.cmin]);
120
+ const {
121
+ fetchedData,
122
+ isPending,
123
+ serverError
124
+ } = usePseudospatialData(plotType);
125
+ useEffect(() => {
126
+ if (!isPending && !serverError && fetchedData) {
127
+ setData(fetchedData.data);
128
+ setLayout(fetchedData.layout);
129
+ updateColorscale(colorscale.current);
130
+ }
131
+ }, [fetchedData, isPending, serverError, sharedScaleRange, updateColorscale]);
132
+ useEffect(() => {
133
+ colorscale.current = dataset.controls.colorScale;
134
+ updateColorscale(colorscale.current);
135
+ }, [dataset.controls.colorScale, updateColorscale]);
136
+ useEffect(() => {
137
+ if (sharedScaleRange) {
138
+ const {
139
+ min,
140
+ max
141
+ } = {
142
+ min: dataset.controls.range[0] * (dataset.controls.valueRange[1] - dataset.controls.valueRange[0]) + dataset.controls.valueRange[0],
143
+ max: dataset.controls.range[1] * (dataset.controls.valueRange[1] - dataset.controls.valueRange[0]) + dataset.controls.valueRange[0]
144
+ };
145
+ setData(d => {
146
+ return _.map(d, trace => {
147
+ const v = trace.meta.value;
148
+ if (v === null) {
149
+ return trace;
150
+ }
151
+ const color = rgbToHex(getColor({
152
+ value: (v - min) / (max - min)
153
+ }));
154
+ return {
155
+ ...trace,
156
+ fillcolor: color,
157
+ line: {
158
+ ...trace.line,
159
+ color: color
160
+ }
161
+ };
162
+ });
163
+ });
164
+ setLayout(l => {
165
+ return {
166
+ ...l,
167
+ coloraxis: {
168
+ ...l.coloraxis,
169
+ cmin: min,
170
+ cmax: max
171
+ }
172
+ };
173
+ });
174
+ }
175
+ }, [dataset.controls.range, dataset.controls.valueMax, dataset.controls.valueMin, dataset.controls.valueRange, getColor, sharedScaleRange]);
176
+ const hasSelections = !!plotType && !!dataset.pseudospatial.maskSet;
177
+ const faSlidersPath = faSliders.icon[4];
178
+ if (!serverError) {
179
+ return /*#__PURE__*/React.createElement("div", {
180
+ className: "cherita-pseudospatial"
181
+ }, /*#__PURE__*/React.createElement(React.Fragment, null, hasSelections && isPending && /*#__PURE__*/React.createElement(LoadingSpinner, null), hasSelections && /*#__PURE__*/React.createElement(Plot, {
182
+ data: data,
183
+ layout: {
184
+ ...layout,
185
+ autosize: true,
186
+ height: height
187
+ },
188
+ useResizeHandler: true,
189
+ className: "cherita-pseudospatial-plot",
190
+ config: {
191
+ displaylogo: false,
192
+ displayModeBar: true,
193
+ modeBarButtonsToAdd: [{
194
+ name: "Open plot controls",
195
+ icon: {
196
+ width: 512,
197
+ height: 512,
198
+ path: faSlidersPath,
199
+ ascent: 512,
200
+ descent: 0
201
+ },
202
+ click: () => setShowControls(prev => !prev)
203
+ }]
204
+ }
205
+ }), hasSelections && showLegend && /*#__PURE__*/React.createElement(Legend, {
206
+ min: layout?.coloraxis?.cmin,
207
+ max: layout?.coloraxis?.cmax,
208
+ addText: plotType === PLOT_TYPES.GENE ? " - Mean expression" : plotType === PLOT_TYPES.CATEGORICAL ? " - %" : plotType === PLOT_TYPES.CONTINUOUS ? " - Mean value" : ""
209
+ })));
210
+ } else {
211
+ return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Alert, {
212
+ variant: "danger"
213
+ }, serverError.message));
214
+ }
215
+ }
216
+
217
+ // @TODO: explore making it a minimap
218
+ export function PseudospatialImage() {
219
+ const dataset = useDataset();
220
+ if (dataset.imageUrl) {
221
+ return /*#__PURE__*/React.createElement(ImageViewer, {
222
+ src: dataset.imageUrl,
223
+ alt: "Pseudospatial reference image"
224
+ });
225
+ } else {
226
+ return /*#__PURE__*/React.createElement(React.Fragment, null);
227
+ }
228
+ }
@@ -0,0 +1,123 @@
1
+ import React, { useEffect, useState } from "react";
2
+ import { faChevronDown } from "@fortawesome/free-solid-svg-icons";
3
+ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
4
+ import _ from "lodash";
5
+ import { ButtonGroup, Dropdown, Form } from "react-bootstrap";
6
+ import { PSEUDOSPATIAL_CATEGORICAL_MODES as MODES, PSEUDOSPATIAL_PLOT_TYPES as PLOT_TYPES } from "../../constants/constants";
7
+ import { useDataset, useDatasetDispatch } from "../../context/DatasetContext";
8
+ import { useFetch } from "../../utils/requests";
9
+ function CategoricalMode() {
10
+ const dataset = useDataset();
11
+ const dispatch = useDatasetDispatch();
12
+ const modeList = _.map(MODES, (m, key) => /*#__PURE__*/React.createElement(Dropdown.Item, {
13
+ key: key,
14
+ active: dataset.pseudospatial.categoricalMode === m,
15
+ onClick: () => {
16
+ dispatch({
17
+ type: "set.pseudospatial.categoricalMode",
18
+ categoricalMode: m.value
19
+ });
20
+ }
21
+ }, _.capitalize(m.name)));
22
+ const mode = _.find(MODES, {
23
+ value: dataset.pseudospatial.categoricalMode
24
+ });
25
+ return /*#__PURE__*/React.createElement(Dropdown, null, /*#__PURE__*/React.createElement(Dropdown.Toggle, {
26
+ variant: "light"
27
+ }, _.capitalize(mode.name)), /*#__PURE__*/React.createElement(Dropdown.Menu, null, modeList));
28
+ }
29
+ function MaskSet() {
30
+ const ENDPOINT = "masks";
31
+ const dataset = useDataset();
32
+ const dispatch = useDatasetDispatch();
33
+ const [maskSets, setMaskSets] = useState(null);
34
+ const [params, setParams] = useState({
35
+ url: dataset.url
36
+ });
37
+ useEffect(() => {
38
+ setParams(p => {
39
+ return {
40
+ ...p,
41
+ url: dataset.url
42
+ };
43
+ });
44
+ }, [dataset.url]);
45
+ const {
46
+ fetchedData,
47
+ isPending,
48
+ serverError
49
+ } = useFetch(ENDPOINT, params, {
50
+ refetchOnMount: false
51
+ });
52
+ useEffect(() => {
53
+ if (!isPending && !serverError) {
54
+ setMaskSets(fetchedData);
55
+ }
56
+ }, [fetchedData, isPending, serverError]);
57
+ const maskSetList = _.map(maskSets, (ms, key) => /*#__PURE__*/React.createElement(Dropdown.Item, {
58
+ key: key,
59
+ active: dataset.pseudospatial.maskSet === key,
60
+ onClick: () => {
61
+ dispatch({
62
+ type: "set.pseudospatial.maskSet",
63
+ maskSet: key
64
+ });
65
+ }
66
+ }, _.capitalize(key)));
67
+ const handleMaskChange = mask => {
68
+ let newMasks = dataset.pseudospatial.maskValues || maskSets?.[dataset.pseudospatial?.maskSet];
69
+ newMasks = newMasks.includes(mask) ? newMasks.filter(m => m !== mask) : [...newMasks, mask];
70
+ if (!_.difference(maskSets?.[dataset.pseudospatial?.maskSet], newMasks).length) {
71
+ newMasks = null;
72
+ }
73
+ dispatch({
74
+ type: "set.pseudospatial.maskValues",
75
+ maskValues: newMasks
76
+ });
77
+ };
78
+ const toggleMasks = () => {
79
+ if (!dataset.pseudospatial.maskValues || dataset.pseudospatial.maskValues?.length === maskSets?.[dataset.pseudospatial?.maskSet]?.length) {
80
+ dispatch({
81
+ type: "set.pseudospatial.maskValues",
82
+ maskValues: []
83
+ });
84
+ } else {
85
+ dispatch({
86
+ type: "set.pseudospatial.maskValues",
87
+ maskValues: null
88
+ });
89
+ }
90
+ };
91
+ const masksList = _.map(maskSets?.[dataset.pseudospatial?.maskSet], mask => /*#__PURE__*/React.createElement(Dropdown.ItemText, {
92
+ key: mask
93
+ }, /*#__PURE__*/React.createElement(Form.Check, {
94
+ type: "checkbox",
95
+ label: mask,
96
+ checked: !dataset.pseudospatial.maskValues || dataset.pseudospatial.maskValues.includes(mask),
97
+ onChange: () => handleMaskChange(mask)
98
+ })));
99
+ const nMasks = dataset.pseudospatial.maskValues ? dataset.pseudospatial.maskValues?.length : maskSets?.[dataset.pseudospatial?.maskSet]?.length || "No";
100
+ const toggleAllChecked = !dataset.pseudospatial.maskValues || dataset.pseudospatial.maskValues?.length === maskSets?.[dataset.pseudospatial?.maskSet]?.length;
101
+ return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Dropdown, null, /*#__PURE__*/React.createElement(Dropdown.Toggle, {
102
+ variant: "light"
103
+ }, _.capitalize(dataset.pseudospatial.maskSet || "Select a mask set")), /*#__PURE__*/React.createElement(Dropdown.Menu, null, /*#__PURE__*/React.createElement(Dropdown.Header, null, "Mask set"), maskSetList)), /*#__PURE__*/React.createElement(Dropdown, null, /*#__PURE__*/React.createElement(Dropdown.Toggle, {
104
+ variant: "light"
105
+ }, nMasks, " masks selected"), /*#__PURE__*/React.createElement(Dropdown.Menu, null, /*#__PURE__*/React.createElement(Dropdown.Header, null, "Masks"), /*#__PURE__*/React.createElement(Dropdown.ItemText, {
106
+ key: "toggle-all"
107
+ }, /*#__PURE__*/React.createElement(Form.Check, {
108
+ type: "checkbox",
109
+ label: "Toggle all",
110
+ checked: toggleAllChecked,
111
+ onChange: toggleMasks
112
+ })), masksList)));
113
+ }
114
+
115
+ // @TODO: add colormap, colorbar slider
116
+ export function PseudospatialToolbar(_ref) {
117
+ let {
118
+ plotType
119
+ } = _ref;
120
+ return /*#__PURE__*/React.createElement("div", {
121
+ className: "cherita-pseudospatial-toolbar"
122
+ }, /*#__PURE__*/React.createElement(ButtonGroup, null, /*#__PURE__*/React.createElement(MaskSet, null)), /*#__PURE__*/React.createElement(ButtonGroup, null, plotType === PLOT_TYPES.CATEGORICAL && /*#__PURE__*/React.createElement(CategoricalMode, null)));
123
+ }