@haniffalab/cherita-react 1.4.1-dev.2025-10-20.528e0f75 → 1.4.1-dev.2025-10-22.61540191
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.
- package/dist/cjs/components/dotplot/Dotplot.js +23 -15
- package/dist/cjs/components/full-page/FullPage.js +32 -30
- package/dist/cjs/components/full-page/PlotAlert.js +36 -0
- package/dist/cjs/components/full-page/PlotTypeSelector.js +77 -39
- package/dist/cjs/components/heatmap/Heatmap.js +23 -15
- package/dist/cjs/components/icons/DotPlotIcon.js +58 -0
- package/dist/cjs/components/icons/HeatmapIcon.js +39 -0
- package/dist/cjs/components/icons/MatrixPlotIcon.1.js +51 -0
- package/dist/cjs/components/icons/MatrixPlotIcon.js +53 -0
- package/dist/cjs/components/icons/ScatterplotIcon.1.js +158 -0
- package/dist/cjs/components/icons/ScatterplotIcon.js +138 -0
- package/dist/cjs/components/icons/ViolinPlotIcon.js +34 -0
- package/dist/cjs/components/matrixplot/Matrixplot.js +25 -17
- package/dist/cjs/components/pseudospatial/Pseudospatial.js +64 -25
- package/dist/cjs/components/pseudospatial/PseudospatialToolbar.js +63 -15
- package/dist/cjs/components/violin/Violin.js +41 -30
- package/dist/cjs/context/DatasetContext.js +1 -1
- package/dist/cjs/context/SettingsContext.js +27 -3
- package/dist/cjs/utils/StyledTooltip.js +39 -0
- package/dist/css/cherita.css +37 -22
- package/dist/css/cherita.css.map +1 -1
- package/dist/esm/components/dotplot/Dotplot.js +22 -13
- package/dist/esm/components/full-page/FullPage.js +6 -3
- package/dist/esm/components/full-page/PlotAlert.js +30 -0
- package/dist/esm/components/full-page/PlotTypeSelector.js +76 -38
- package/dist/esm/components/heatmap/Heatmap.js +22 -13
- package/dist/esm/components/icons/DotPlotIcon.js +52 -0
- package/dist/esm/components/icons/HeatmapIcon.js +33 -0
- package/dist/esm/components/icons/MatrixPlotIcon.1.js +45 -0
- package/dist/esm/components/icons/MatrixPlotIcon.js +47 -0
- package/dist/esm/components/icons/ScatterplotIcon.1.js +152 -0
- package/dist/esm/components/icons/ScatterplotIcon.js +132 -0
- package/dist/esm/components/icons/ViolinPlotIcon.js +28 -0
- package/dist/esm/components/matrixplot/Matrixplot.js +24 -15
- package/dist/esm/components/pseudospatial/Pseudospatial.js +58 -18
- package/dist/esm/components/pseudospatial/PseudospatialToolbar.js +52 -4
- package/dist/esm/components/violin/Violin.js +36 -24
- package/dist/esm/context/DatasetContext.js +1 -1
- package/dist/esm/context/SettingsContext.js +27 -3
- package/dist/esm/utils/StyledTooltip.js +33 -0
- package/package.json +2 -2
- package/scss/cherita.scss +19 -1
- package/scss/components/layouts.scss +2 -21
- package/scss/components/plotly.scss +37 -26
- package/scss/components/plots.scss +14 -1
- package/dist/assets/images/plots/dotplot.svg +0 -152
- package/dist/assets/images/plots/heatmap.svg +0 -193
- package/dist/assets/images/plots/matrixplot.svg +0 -275
- package/dist/assets/images/plots/scatterplot.svg +0 -198
- package/dist/assets/images/plots/violin.svg +0 -50
|
@@ -3,9 +3,8 @@ 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
|
|
7
|
-
import {
|
|
8
|
-
import { faSliders } from "@fortawesome/free-solid-svg-icons";
|
|
6
|
+
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
7
|
+
import { faEye, faSliders } from "@fortawesome/free-solid-svg-icons";
|
|
9
8
|
import _ from "lodash";
|
|
10
9
|
import { Alert } from "react-bootstrap";
|
|
11
10
|
import Plot from "react-plotly.js";
|
|
@@ -19,7 +18,6 @@ import { Legend } from "../../utils/Legend";
|
|
|
19
18
|
import { LoadingSpinner } from "../../utils/LoadingIndicators";
|
|
20
19
|
import { useDebouncedFetch } from "../../utils/requests";
|
|
21
20
|
import { useSelectedObs, useSelectedVar } from "../../utils/Resolver";
|
|
22
|
-
library.add(faSliders);
|
|
23
21
|
function usePseudospatialData(plotType) {
|
|
24
22
|
const ENDPOINT = "pseudospatial";
|
|
25
23
|
const dataset = useDataset();
|
|
@@ -73,7 +71,7 @@ function usePseudospatialData(plotType) {
|
|
|
73
71
|
});
|
|
74
72
|
}
|
|
75
73
|
export function Pseudospatial(_ref) {
|
|
76
|
-
var _layout$coloraxis3, _layout$coloraxis4;
|
|
74
|
+
var _layout$coloraxis3, _layout$coloraxis4, _settings$pseudospati2;
|
|
77
75
|
let {
|
|
78
76
|
showLegend = true,
|
|
79
77
|
sharedScaleRange = false,
|
|
@@ -82,6 +80,9 @@ export function Pseudospatial(_ref) {
|
|
|
82
80
|
plotType,
|
|
83
81
|
setPlotType
|
|
84
82
|
} = _ref;
|
|
83
|
+
const {
|
|
84
|
+
imageUrl
|
|
85
|
+
} = useDataset();
|
|
85
86
|
const settings = useSettings();
|
|
86
87
|
const dispatch = useSettingsDispatch();
|
|
87
88
|
const [data, setData] = useState([]);
|
|
@@ -188,7 +189,48 @@ export function Pseudospatial(_ref) {
|
|
|
188
189
|
}
|
|
189
190
|
}, [settings.controls.range, settings.controls.valueMax, settings.controls.valueMin, getColor, sharedScaleRange, valueMax, valueMin]);
|
|
190
191
|
const hasSelections = !!plotType && !!settings.pseudospatial.maskSet;
|
|
191
|
-
const
|
|
192
|
+
const images = useMemo(() => {
|
|
193
|
+
if (imageUrl) {
|
|
194
|
+
return [_objectSpread({
|
|
195
|
+
source: imageUrl,
|
|
196
|
+
xref: "paper",
|
|
197
|
+
yref: "paper",
|
|
198
|
+
x: 0.5,
|
|
199
|
+
y: 0.5,
|
|
200
|
+
sizex: 1,
|
|
201
|
+
sizey: 1,
|
|
202
|
+
sizing: "contain",
|
|
203
|
+
layer: "above",
|
|
204
|
+
xanchor: "center",
|
|
205
|
+
yanchor: "middle",
|
|
206
|
+
name: "Reference Image"
|
|
207
|
+
}, settings.pseudospatial.refImg)];
|
|
208
|
+
}
|
|
209
|
+
return [];
|
|
210
|
+
}, [imageUrl, settings.pseudospatial.refImg]);
|
|
211
|
+
const modeBarButtons = useMemo(() => {
|
|
212
|
+
var _settings$pseudospati;
|
|
213
|
+
const isRefImgVisible = (_settings$pseudospati = settings.pseudospatial) === null || _settings$pseudospati === void 0 || (_settings$pseudospati = _settings$pseudospati.refImg) === null || _settings$pseudospati === void 0 ? void 0 : _settings$pseudospati.visible;
|
|
214
|
+
return [{
|
|
215
|
+
name: "Open plot controls",
|
|
216
|
+
icon: {
|
|
217
|
+
width: 512,
|
|
218
|
+
height: 512,
|
|
219
|
+
path: faSliders.icon[4]
|
|
220
|
+
},
|
|
221
|
+
click: () => setShowControls(prev => !prev)
|
|
222
|
+
}, ...(imageUrl ? [{
|
|
223
|
+
name: isRefImgVisible ? "Hide reference image" : "Show reference image",
|
|
224
|
+
icon: {
|
|
225
|
+
width: 600,
|
|
226
|
+
height: 512,
|
|
227
|
+
path: faEye.icon[4]
|
|
228
|
+
},
|
|
229
|
+
click: () => dispatch({
|
|
230
|
+
type: "toggle.pseudospatial.refImg.visible"
|
|
231
|
+
})
|
|
232
|
+
}] : [])];
|
|
233
|
+
}, [dispatch, imageUrl, setShowControls, (_settings$pseudospati2 = settings.pseudospatial) === null || _settings$pseudospati2 === void 0 || (_settings$pseudospati2 = _settings$pseudospati2.refImg) === null || _settings$pseudospati2 === void 0 ? void 0 : _settings$pseudospati2.visible]);
|
|
192
234
|
if (!_.keys(settings.data.pseudospatial).length) {
|
|
193
235
|
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Alert, {
|
|
194
236
|
variant: "warning"
|
|
@@ -201,24 +243,22 @@ export function Pseudospatial(_ref) {
|
|
|
201
243
|
data: data,
|
|
202
244
|
layout: _objectSpread(_objectSpread({}, layout), {}, {
|
|
203
245
|
autosize: true,
|
|
204
|
-
height: height
|
|
246
|
+
height: height,
|
|
247
|
+
margin: {
|
|
248
|
+
l: 0,
|
|
249
|
+
r: 0,
|
|
250
|
+
t: 0,
|
|
251
|
+
b: 0,
|
|
252
|
+
pad: 0
|
|
253
|
+
},
|
|
254
|
+
images: images
|
|
205
255
|
}),
|
|
206
256
|
useResizeHandler: true,
|
|
207
257
|
className: "cherita-pseudospatial-plot",
|
|
208
258
|
config: {
|
|
209
259
|
displaylogo: false,
|
|
210
260
|
displayModeBar: true,
|
|
211
|
-
modeBarButtonsToAdd:
|
|
212
|
-
name: "Open plot controls",
|
|
213
|
-
icon: {
|
|
214
|
-
width: 512,
|
|
215
|
-
height: 512,
|
|
216
|
-
path: faSlidersPath,
|
|
217
|
-
ascent: 512,
|
|
218
|
-
descent: 0
|
|
219
|
-
},
|
|
220
|
-
click: () => setShowControls(prev => !prev)
|
|
221
|
-
}]
|
|
261
|
+
modeBarButtonsToAdd: modeBarButtons
|
|
222
262
|
}
|
|
223
263
|
}), hasSelections && showLegend && /*#__PURE__*/React.createElement(Legend, {
|
|
224
264
|
min: layout === null || layout === void 0 || (_layout$coloraxis5 = layout.coloraxis) === null || _layout$coloraxis5 === void 0 ? void 0 : _layout$coloraxis5.cmin,
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { useState } from "react";
|
|
2
|
+
import { Box, Slider, Typography } from "@mui/material";
|
|
2
3
|
import _ from "lodash";
|
|
3
4
|
import { ButtonGroup, Dropdown, Form } from "react-bootstrap";
|
|
4
5
|
import { PSEUDOSPATIAL_CATEGORICAL_MODES as MODES, PSEUDOSPATIAL_PLOT_TYPES as PLOT_TYPES } from "../../constants/constants";
|
|
6
|
+
import { useDataset } from "../../context/DatasetContext";
|
|
5
7
|
import { useSettings, useSettingsDispatch } from "../../context/SettingsContext";
|
|
6
8
|
function CategoricalMode() {
|
|
7
9
|
const settings = useSettings();
|
|
@@ -89,13 +91,59 @@ function MaskSet() {
|
|
|
89
91
|
onChange: toggleMasks
|
|
90
92
|
})), masksList)));
|
|
91
93
|
}
|
|
94
|
+
function OpacitySlider(_ref) {
|
|
95
|
+
let {
|
|
96
|
+
opacity,
|
|
97
|
+
setOpacity
|
|
98
|
+
} = _ref;
|
|
99
|
+
const [sliderValue, setSliderValue] = useState(opacity);
|
|
100
|
+
return /*#__PURE__*/React.createElement(Box, {
|
|
101
|
+
className: "w-100"
|
|
102
|
+
}, /*#__PURE__*/React.createElement(Typography, {
|
|
103
|
+
id: "opacity-range",
|
|
104
|
+
gutterBottom: true
|
|
105
|
+
}, "Reference image opacity"), /*#__PURE__*/React.createElement("div", {
|
|
106
|
+
className: "px-4"
|
|
107
|
+
}, /*#__PURE__*/React.createElement(Slider, {
|
|
108
|
+
"aria-labelledby": "opacity-range",
|
|
109
|
+
min: 0,
|
|
110
|
+
max: 1,
|
|
111
|
+
step: 0.05,
|
|
112
|
+
value: sliderValue,
|
|
113
|
+
onChange: (_e, value) => setSliderValue(value),
|
|
114
|
+
onChangeCommitted: (_e, value) => setOpacity(value),
|
|
115
|
+
valueLabelDisplay: "auto",
|
|
116
|
+
getAriaValueText: value => "".concat(value * 100, "%"),
|
|
117
|
+
valueLabelFormat: value => "".concat((value * 100).toFixed(0), "%"),
|
|
118
|
+
marks: [{
|
|
119
|
+
value: 0,
|
|
120
|
+
label: "0%"
|
|
121
|
+
}, {
|
|
122
|
+
value: 1,
|
|
123
|
+
label: "100%"
|
|
124
|
+
}]
|
|
125
|
+
})));
|
|
126
|
+
}
|
|
92
127
|
|
|
93
128
|
// @TODO: add colormap, colorbar slider
|
|
94
|
-
export function PseudospatialToolbar(
|
|
129
|
+
export function PseudospatialToolbar(_ref2) {
|
|
95
130
|
let {
|
|
96
131
|
plotType
|
|
97
|
-
} =
|
|
132
|
+
} = _ref2;
|
|
133
|
+
const {
|
|
134
|
+
imageUrl
|
|
135
|
+
} = useDataset();
|
|
136
|
+
const settings = useSettings();
|
|
137
|
+
const dispatch = useSettingsDispatch();
|
|
98
138
|
return /*#__PURE__*/React.createElement("div", {
|
|
99
139
|
className: "cherita-pseudospatial-toolbar"
|
|
100
|
-
}, /*#__PURE__*/React.createElement(ButtonGroup, null, /*#__PURE__*/React.createElement(MaskSet, null)), /*#__PURE__*/React.createElement(ButtonGroup, null, plotType === PLOT_TYPES.CATEGORICAL && /*#__PURE__*/React.createElement(CategoricalMode, null))
|
|
140
|
+
}, /*#__PURE__*/React.createElement(ButtonGroup, null, /*#__PURE__*/React.createElement(MaskSet, null)), /*#__PURE__*/React.createElement(ButtonGroup, null, plotType === PLOT_TYPES.CATEGORICAL && /*#__PURE__*/React.createElement(CategoricalMode, null)), imageUrl && /*#__PURE__*/React.createElement(OpacitySlider, {
|
|
141
|
+
opacity: settings.pseudospatial.refImg.opacity,
|
|
142
|
+
setOpacity: opacity => {
|
|
143
|
+
dispatch({
|
|
144
|
+
type: "set.pseudospatial.refImg.opacity",
|
|
145
|
+
opacity: opacity
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
}));
|
|
101
149
|
}
|
|
@@ -3,11 +3,11 @@ 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
|
|
6
|
+
import { useEffect, useState } from "react";
|
|
7
7
|
import { faCircleInfo } from "@fortawesome/free-solid-svg-icons";
|
|
8
8
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
|
9
9
|
import _ from "lodash";
|
|
10
|
-
import {
|
|
10
|
+
import { Badge, Button } from "react-bootstrap";
|
|
11
11
|
import Plot from "react-plotly.js";
|
|
12
12
|
import { PLOTLY_MODEBAR_BUTTONS, VIOLIN_MODES } from "../../constants/constants";
|
|
13
13
|
import { useDataset } from "../../context/DatasetContext";
|
|
@@ -16,6 +16,8 @@ import { useSettings } from "../../context/SettingsContext";
|
|
|
16
16
|
import { LoadingSpinner } from "../../utils/LoadingIndicators";
|
|
17
17
|
import { useDebouncedFetch } from "../../utils/requests";
|
|
18
18
|
import { useSelectedMultiVar, useSelectedObs, useSelectedVar } from "../../utils/Resolver";
|
|
19
|
+
import { StyledTooltip } from "../../utils/StyledTooltip";
|
|
20
|
+
import { PlotAlert } from "../full-page/PlotAlert";
|
|
19
21
|
import { ControlsPlotlyToolbar, ObsPlotlyToolbar, VarPlotlyToolbar } from "../toolbar/Toolbar";
|
|
20
22
|
export function Violin(_ref) {
|
|
21
23
|
let {
|
|
@@ -25,7 +27,9 @@ export function Violin(_ref) {
|
|
|
25
27
|
showCtrlsBtn = false,
|
|
26
28
|
setShowObs,
|
|
27
29
|
setShowVars,
|
|
28
|
-
setShowControls
|
|
30
|
+
setShowControls,
|
|
31
|
+
plotType,
|
|
32
|
+
setPlotType
|
|
29
33
|
} = _ref;
|
|
30
34
|
const ENDPOINT = "violin";
|
|
31
35
|
const dataset = useDataset();
|
|
@@ -152,39 +156,47 @@ export function Violin(_ref) {
|
|
|
152
156
|
modeBarButtons: modeBarButtons
|
|
153
157
|
}
|
|
154
158
|
})), (fetchedData === null || fetchedData === void 0 ? void 0 : fetchedData.resampled) && /*#__PURE__*/React.createElement("div", {
|
|
155
|
-
className: "
|
|
156
|
-
}, /*#__PURE__*/React.createElement(
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
}, /*#__PURE__*/React.createElement(
|
|
160
|
-
|
|
161
|
-
overlay: /*#__PURE__*/React.createElement(Tooltip, null, "Resampled to 100K values following a Monte Carlo style approach to help ensure resampled data is a good representation of the original dataset's distribution.")
|
|
159
|
+
className: "resampled-tooltip-container"
|
|
160
|
+
}, /*#__PURE__*/React.createElement(StyledTooltip, {
|
|
161
|
+
title: /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("strong", null, "Note:"), " This plot uses resampled data to improve performance, so values may differ slightly from the full dataset. The data were resampled to exactly 100,000 values using a Monte Carlo\u2013style approach to provide a representative view of the full distribution while reducing processing time."),
|
|
162
|
+
placement: "bottom"
|
|
163
|
+
}, /*#__PURE__*/React.createElement(Badge, {
|
|
164
|
+
bg: "info"
|
|
162
165
|
}, /*#__PURE__*/React.createElement(FontAwesomeIcon, {
|
|
166
|
+
className: "fs-6",
|
|
163
167
|
icon: faCircleInfo
|
|
164
|
-
})
|
|
168
|
+
}), /*#__PURE__*/React.createElement("span", {
|
|
169
|
+
className: "d-none d-lg-inline ms-2 fs-6 text-uppercase"
|
|
170
|
+
}, "Resampled"))))));
|
|
165
171
|
}
|
|
166
|
-
return /*#__PURE__*/React.createElement(
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
172
|
+
return /*#__PURE__*/React.createElement(PlotAlert, {
|
|
173
|
+
variant: "info",
|
|
174
|
+
heading: "Violin plot",
|
|
175
|
+
plotType: plotType,
|
|
176
|
+
setPlotType: setPlotType
|
|
177
|
+
}, mode === VIOLIN_MODES.MULTIKEY && /*#__PURE__*/React.createElement("p", {
|
|
178
|
+
className: "p-0 m-0"
|
|
179
|
+
}, "To begin, select one or more", " ", showVarsBtn ? /*#__PURE__*/React.createElement(Button, {
|
|
171
180
|
variant: "link",
|
|
172
181
|
className: "border-0 p-0 align-baseline",
|
|
173
182
|
onClick: setShowVars
|
|
174
|
-
}, "features") : "features"), mode === VIOLIN_MODES.GROUPBY && /*#__PURE__*/React.createElement(
|
|
175
|
-
|
|
176
|
-
}, "
|
|
183
|
+
}, "features") : "features", " ", "to display their expression distributions across all observations."), mode === VIOLIN_MODES.GROUPBY && /*#__PURE__*/React.createElement("p", {
|
|
184
|
+
className: "p-0 m-0"
|
|
185
|
+
}, "To begin, select a", " ", showObsBtn ? /*#__PURE__*/React.createElement(Button, {
|
|
177
186
|
variant: "link",
|
|
178
187
|
className: "border-0 p-0 align-baseline",
|
|
179
188
|
onClick: setShowObs
|
|
180
|
-
}, "
|
|
189
|
+
}, "category") : "category", " ", "to group observations, and choose a", " ", showVarsBtn ? /*#__PURE__*/React.createElement(Button, {
|
|
181
190
|
variant: "link",
|
|
182
191
|
className: "border-0 p-0 align-baseline",
|
|
183
192
|
onClick: setShowVars
|
|
184
|
-
}, "feature") : "feature"));
|
|
193
|
+
}, "feature") : "feature", " ", "to view its distribution within each group."));
|
|
185
194
|
} else {
|
|
186
|
-
return /*#__PURE__*/React.createElement(
|
|
187
|
-
variant: "danger"
|
|
188
|
-
|
|
195
|
+
return /*#__PURE__*/React.createElement(PlotAlert, {
|
|
196
|
+
variant: "danger",
|
|
197
|
+
heading: "Violin plot",
|
|
198
|
+
plotType: plotType,
|
|
199
|
+
setPlotType: setPlotType
|
|
200
|
+
}, serverError.message || "An unexpected error occurred while generating the plot.");
|
|
189
201
|
}
|
|
190
202
|
}
|
|
@@ -62,7 +62,11 @@ const initialSettings = {
|
|
|
62
62
|
pseudospatial: {
|
|
63
63
|
maskSet: null,
|
|
64
64
|
maskValues: null,
|
|
65
|
-
categoricalMode: PSEUDOSPATIAL_CATEGORICAL_MODES.ACROSS.value
|
|
65
|
+
categoricalMode: PSEUDOSPATIAL_CATEGORICAL_MODES.ACROSS.value,
|
|
66
|
+
refImg: {
|
|
67
|
+
visible: false,
|
|
68
|
+
opacity: 1
|
|
69
|
+
}
|
|
66
70
|
},
|
|
67
71
|
// dataset resolved values
|
|
68
72
|
data: {
|
|
@@ -158,7 +162,7 @@ export function SettingsProvider(_ref2) {
|
|
|
158
162
|
|
|
159
163
|
// If the buster is not set or does not match the current package version,
|
|
160
164
|
// reset localSettings to avoid stale data
|
|
161
|
-
if (!buster || buster !== "1.4.1-dev.2025-10-
|
|
165
|
+
if (!buster || buster !== "1.4.1-dev.2025-10-22.61540191") {
|
|
162
166
|
localSettings = {};
|
|
163
167
|
}
|
|
164
168
|
const initSettings = useRef(initializer({
|
|
@@ -183,7 +187,7 @@ export function SettingsProvider(_ref2) {
|
|
|
183
187
|
if (canOverrideSettings && settings) {
|
|
184
188
|
try {
|
|
185
189
|
localStorage.setItem(DATASET_STORAGE_KEY, JSON.stringify(_objectSpread({
|
|
186
|
-
buster: "1.4.1-dev.2025-10-
|
|
190
|
+
buster: "1.4.1-dev.2025-10-22.61540191" || "0.0.0",
|
|
187
191
|
timestamp: Date.now()
|
|
188
192
|
}, _.omit(settings, "data"))));
|
|
189
193
|
} catch (err) {
|
|
@@ -708,6 +712,26 @@ function settingsReducer(settings, action) {
|
|
|
708
712
|
})
|
|
709
713
|
});
|
|
710
714
|
}
|
|
715
|
+
case "toggle.pseudospatial.refImg.visible":
|
|
716
|
+
{
|
|
717
|
+
return _objectSpread(_objectSpread({}, settings), {}, {
|
|
718
|
+
pseudospatial: _objectSpread(_objectSpread({}, settings.pseudospatial), {}, {
|
|
719
|
+
refImg: _objectSpread(_objectSpread({}, settings.pseudospatial.refImg), {}, {
|
|
720
|
+
visible: !settings.pseudospatial.refImg.visible
|
|
721
|
+
})
|
|
722
|
+
})
|
|
723
|
+
});
|
|
724
|
+
}
|
|
725
|
+
case "set.pseudospatial.refImg.opacity":
|
|
726
|
+
{
|
|
727
|
+
return _objectSpread(_objectSpread({}, settings), {}, {
|
|
728
|
+
pseudospatial: _objectSpread(_objectSpread({}, settings.pseudospatial), {}, {
|
|
729
|
+
refImg: _objectSpread(_objectSpread({}, settings.pseudospatial.refImg), {}, {
|
|
730
|
+
opacity: action.opacity
|
|
731
|
+
})
|
|
732
|
+
})
|
|
733
|
+
});
|
|
734
|
+
}
|
|
711
735
|
default:
|
|
712
736
|
{
|
|
713
737
|
throw Error("Unknown action: " + action.type);
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
const _excluded = ["className"];
|
|
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); }
|
|
3
|
+
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
|
+
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 { styled, Tooltip, tooltipClasses } from "@mui/material";
|
|
6
|
+
export const StyledTooltip = styled(_ref => {
|
|
7
|
+
let {
|
|
8
|
+
className
|
|
9
|
+
} = _ref,
|
|
10
|
+
props = _objectWithoutProperties(_ref, _excluded);
|
|
11
|
+
return /*#__PURE__*/React.createElement(Tooltip, _extends({}, props, {
|
|
12
|
+
classes: {
|
|
13
|
+
popper: className
|
|
14
|
+
}
|
|
15
|
+
}));
|
|
16
|
+
})(_ref2 => {
|
|
17
|
+
let {
|
|
18
|
+
theme
|
|
19
|
+
} = _ref2;
|
|
20
|
+
return {
|
|
21
|
+
["& .".concat(tooltipClasses.tooltip)]: {
|
|
22
|
+
backgroundColor: "#000",
|
|
23
|
+
color: "#fff",
|
|
24
|
+
maxWidth: 220,
|
|
25
|
+
fontSize: 13,
|
|
26
|
+
borderRadius: 4,
|
|
27
|
+
padding: theme.spacing(0.5, 1),
|
|
28
|
+
whiteSpace: "pre-line",
|
|
29
|
+
textAlign: "center",
|
|
30
|
+
boxShadow: "0 0.25rem 0.75rem rgba(0, 0, 0, 0.1)"
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@haniffalab/cherita-react",
|
|
3
|
-
"version": "1.4.1-dev.2025-10-
|
|
3
|
+
"version": "1.4.1-dev.2025-10-22.61540191",
|
|
4
4
|
"author": "Haniffa Lab",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"keywords": [
|
|
@@ -128,5 +128,5 @@
|
|
|
128
128
|
"url": "https://github.com/haniffalab/cherita-react/issues"
|
|
129
129
|
},
|
|
130
130
|
"homepage": "https://github.com/haniffalab/cherita-react#readme",
|
|
131
|
-
"prereleaseSha": "
|
|
131
|
+
"prereleaseSha": "615401914075590f2159adb28a6db12e0d02b720"
|
|
132
132
|
}
|
package/scss/cherita.scss
CHANGED
|
@@ -428,4 +428,22 @@ $gauge-padding: 0.15rem;
|
|
|
428
428
|
|
|
429
429
|
input[type="checkbox"] {
|
|
430
430
|
cursor: pointer;
|
|
431
|
-
}
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
.ps-xs-1 {
|
|
434
|
+
padding-left: 0.15rem !important;
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
.resampled-tooltip-container {
|
|
438
|
+
position: absolute;
|
|
439
|
+
bottom: 16px;
|
|
440
|
+
right: 16px;
|
|
441
|
+
z-index: 10;
|
|
442
|
+
width: max-content;
|
|
443
|
+
|
|
444
|
+
@media (min-width: 991px) {
|
|
445
|
+
top: 16px;
|
|
446
|
+
left: 16px;
|
|
447
|
+
bottom: auto;
|
|
448
|
+
}
|
|
449
|
+
}
|
|
@@ -97,21 +97,6 @@
|
|
|
97
97
|
}
|
|
98
98
|
}
|
|
99
99
|
|
|
100
|
-
.sidebar-plotselector {
|
|
101
|
-
padding: 6px;
|
|
102
|
-
border-bottom: 1px solid #dee2e6;
|
|
103
|
-
|
|
104
|
-
.plotselector-icon {
|
|
105
|
-
padding-bottom: 2px;
|
|
106
|
-
cursor: pointer;
|
|
107
|
-
|
|
108
|
-
.active {
|
|
109
|
-
opacity: 1;
|
|
110
|
-
border-bottom: 2px solid #007bff;
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
|
|
115
100
|
.sidebar-pseudospatial {
|
|
116
101
|
padding: 10px;
|
|
117
102
|
border-bottom: 1px solid #dee2e6;
|
|
@@ -182,9 +167,9 @@
|
|
|
182
167
|
}
|
|
183
168
|
|
|
184
169
|
.cherita-app-canvas {
|
|
185
|
-
@extend .p-
|
|
170
|
+
@extend .p-0;
|
|
186
171
|
flex: 1 1 auto;
|
|
187
|
-
min-width:
|
|
172
|
+
min-width: 375px;
|
|
188
173
|
position: relative;
|
|
189
174
|
max-height: 100%;
|
|
190
175
|
display: flex;
|
|
@@ -211,7 +196,3 @@
|
|
|
211
196
|
}
|
|
212
197
|
}
|
|
213
198
|
}
|
|
214
|
-
|
|
215
|
-
.ps-xs-1 {
|
|
216
|
-
padding-left: 0.15rem !important;
|
|
217
|
-
}
|
|
@@ -1,35 +1,46 @@
|
|
|
1
|
-
|
|
1
|
+
// Plotly modebar customisation
|
|
2
|
+
.js-plotly-plot {
|
|
3
|
+
.plotly {
|
|
4
|
+
.modebar {
|
|
5
|
+
top: 16px;
|
|
6
|
+
right: 0;
|
|
2
7
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
+
// Each button group in the modebar
|
|
9
|
+
.modebar-group {
|
|
10
|
+
@extend .bg-primary;
|
|
11
|
+
@extend .mx-1;
|
|
12
|
+
border-radius: 5px;
|
|
13
|
+
padding: 4px !important;
|
|
8
14
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
// Individual buttons
|
|
16
|
+
.modebar-btn {
|
|
17
|
+
display: inline-flex;
|
|
18
|
+
justify-content: center;
|
|
19
|
+
align-items: center;
|
|
20
|
+
position: relative;
|
|
21
|
+
font-size: 1.25rem;
|
|
22
|
+
padding: 0.25rem;
|
|
23
|
+
height: auto;
|
|
24
|
+
cursor: pointer;
|
|
25
|
+
line-height: normal;
|
|
18
26
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
27
|
+
svg {
|
|
28
|
+
position: relative;
|
|
29
|
+
top: 1px;
|
|
22
30
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
31
|
+
path {
|
|
32
|
+
fill: white !important;
|
|
33
|
+
color: white !important;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
26
36
|
}
|
|
27
37
|
}
|
|
38
|
+
|
|
39
|
+
// Hover effect for modebar buttons except watermark
|
|
40
|
+
&--hover > :not(.watermark) {
|
|
41
|
+
opacity: 1;
|
|
42
|
+
transition: opacity 0.3s;
|
|
43
|
+
}
|
|
28
44
|
}
|
|
29
45
|
}
|
|
30
46
|
}
|
|
31
|
-
|
|
32
|
-
.js-plotly-plot .plotly .modebar--hover > :not(.watermark) {
|
|
33
|
-
opacity: 0.5;
|
|
34
|
-
transition: opacity 0.3s;
|
|
35
|
-
}
|
|
@@ -1,11 +1,24 @@
|
|
|
1
1
|
.cherita-spatial-controls {
|
|
2
2
|
position: absolute;
|
|
3
|
-
z-index: 10;
|
|
4
3
|
top: 1rem;
|
|
5
4
|
left: 1rem;
|
|
5
|
+
z-index: 10;
|
|
6
6
|
width: 3rem;
|
|
7
|
+
|
|
8
|
+
// Target buttons inside the controls
|
|
7
9
|
.btn {
|
|
8
10
|
padding-left: 0;
|
|
9
11
|
padding-right: 0;
|
|
10
12
|
}
|
|
11
13
|
}
|
|
14
|
+
|
|
15
|
+
.plotselector {
|
|
16
|
+
padding: 0 10px;
|
|
17
|
+
border-bottom: 1px solid #dee2e6;
|
|
18
|
+
|
|
19
|
+
// Individual plot selector icons
|
|
20
|
+
.plotselector-icon {
|
|
21
|
+
padding: 6px;
|
|
22
|
+
cursor: pointer;
|
|
23
|
+
}
|
|
24
|
+
}
|