@haniffalab/cherita-react 0.2.1 → 1.0.0-dev.2025-03-07.aedc1788
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/LICENSE +21 -0
- package/README.md +7 -1
- package/dist/components/full-page/FullPage.js +15 -38
- package/dist/components/full-page/FullPagePseudospatial.js +159 -0
- package/dist/components/obs-list/ObsItem.js +114 -20
- package/dist/components/obs-list/ObsList.js +57 -16
- package/dist/components/obs-list/ObsToolbar.js +4 -4
- package/dist/components/offcanvas/index.js +3 -2
- package/dist/components/pseudospatial/Pseudospatial.js +32 -9
- package/dist/components/pseudospatial/PseudospatialToolbar.js +2 -0
- package/dist/components/scatterplot/Scatterplot.js +1 -1
- package/dist/context/DatasetContext.js +11 -6
- package/dist/css/cherita.css +428 -230
- package/dist/css/cherita.css.map +1 -1
- package/dist/helpers/map-helper.js +21 -16
- package/dist/helpers/zarr-helper.js +63 -57
- package/dist/index.js +15 -14
- package/dist/utils/VirtualizedList.js +2 -1
- package/dist/utils/requests.js +14 -2
- package/dist/utils/zarrData.js +22 -12
- package/package.json +27 -20
- package/scss/cherita.scss +89 -47
- package/scss/components/layouts.scss +101 -0
- package/scss/components/plotly.scss +30 -0
- package/scss/components/plots.scss +13 -0
- package/scss/components/scrollbars.scss +18 -0
- package/dist/components/pseudospatial/PseudospatialControls.js +0 -11
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2023
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,9 +1,15 @@
|
|
|
1
1
|
[](https://github.com/haniffalab/cherita-react/actions/workflows/npm-publish.yml)
|
|
2
2
|
[](https://github.com/haniffalab/cherita-react/actions/workflows/npm-publish-dev.yml)
|
|
3
3
|
[](https://www.npmjs.com/package/@haniffalab/cherita-react)
|
|
4
|
+
[](https://github.com/haniffalab/cherita-react/actions/workflows/tests.yml)
|
|
4
5
|
[](https://codecov.io/gh/haniffalab/cherita-react)
|
|
5
6
|
|
|
6
|
-
# Cherita
|
|
7
|
+
# Cherita React
|
|
8
|
+
|
|
9
|
+
[](https://default-dot-haniffa-lab.nw.r.appspot.com/)
|
|
10
|
+
[](https://doi.org/10.5281/zenodo.14244809)
|
|
11
|
+
|
|
12
|
+
React component library designed for data visualisation and analysis of single-cell and spatial multi-omics data. This library provides a set of reusable and customisable components that can be used to used to build study narratives.
|
|
7
13
|
|
|
8
14
|
## Development
|
|
9
15
|
|
|
@@ -5,7 +5,6 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.FullPage = FullPage;
|
|
7
7
|
exports.FullPagePlots = FullPagePlots;
|
|
8
|
-
exports.FullPagePseudospatial = FullPagePseudospatial;
|
|
9
8
|
exports.FullPageScatterplot = FullPageScatterplot;
|
|
10
9
|
var _react = _interopRequireWildcard(require("react"));
|
|
11
10
|
var _reactBootstrap = require("react-bootstrap");
|
|
@@ -16,7 +15,6 @@ var _Heatmap = require("../heatmap/Heatmap");
|
|
|
16
15
|
var _Matrixplot = require("../matrixplot/Matrixplot");
|
|
17
16
|
var _ObsList = require("../obs-list/ObsList");
|
|
18
17
|
var _offcanvas = require("../offcanvas");
|
|
19
|
-
var _Pseudospatial = require("../pseudospatial/Pseudospatial");
|
|
20
18
|
var _Scatterplot = require("../scatterplot/Scatterplot");
|
|
21
19
|
var _ScatterplotControls = require("../scatterplot/ScatterplotControls");
|
|
22
20
|
var _SearchBar = require("../search-bar/SearchBar");
|
|
@@ -30,46 +28,46 @@ function FullPage({
|
|
|
30
28
|
varMode = _constants.SELECTION_MODES.SINGLE,
|
|
31
29
|
...props
|
|
32
30
|
}) {
|
|
33
|
-
const
|
|
31
|
+
const appRef = (0, _react.useRef)();
|
|
32
|
+
const [appDimensions, setAppDimensions] = (0, _react.useState)({
|
|
33
|
+
width: 0,
|
|
34
|
+
height: 0
|
|
35
|
+
});
|
|
34
36
|
const [showObs, setShowObs] = (0, _react.useState)(false);
|
|
35
37
|
const [showObsm, setShowObsm] = (0, _react.useState)(false);
|
|
36
38
|
const [showVars, setShowVars] = (0, _react.useState)(false);
|
|
37
39
|
const [showControls, setShowControls] = (0, _react.useState)(false);
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
});
|
|
42
|
-
(0, _react.useLayoutEffect)(() => {
|
|
43
|
-
function updateDimensions() {
|
|
44
|
-
if (targetRef.current) {
|
|
40
|
+
(0, _react.useEffect)(() => {
|
|
41
|
+
const updateDimensions = () => {
|
|
42
|
+
if (appRef.current) {
|
|
45
43
|
// Get the distance from the top of the page to the target element
|
|
46
|
-
const rect =
|
|
44
|
+
const rect = appRef.current.getBoundingClientRect();
|
|
47
45
|
const distanceFromTop = rect.top + window.scrollY;
|
|
48
46
|
|
|
49
47
|
// Calculate the available height for the Cherita app
|
|
50
48
|
const availableHeight = window.innerHeight - distanceFromTop;
|
|
51
49
|
|
|
52
50
|
// Update the dimensions to fit the viewport minus the navbar height
|
|
53
|
-
|
|
54
|
-
width:
|
|
51
|
+
setAppDimensions({
|
|
52
|
+
width: appRef.current.offsetWidth,
|
|
55
53
|
height: availableHeight
|
|
56
54
|
});
|
|
57
55
|
}
|
|
58
|
-
}
|
|
56
|
+
};
|
|
59
57
|
window.addEventListener("resize", updateDimensions);
|
|
60
58
|
updateDimensions(); // Initial update
|
|
61
59
|
return () => window.removeEventListener("resize", updateDimensions);
|
|
62
60
|
}, []);
|
|
63
61
|
return /*#__PURE__*/_react.default.createElement("div", {
|
|
64
|
-
ref:
|
|
62
|
+
ref: appRef,
|
|
65
63
|
className: "cherita-app",
|
|
66
64
|
style: {
|
|
67
|
-
height:
|
|
65
|
+
height: appDimensions.height
|
|
68
66
|
}
|
|
69
67
|
}, /*#__PURE__*/_react.default.createElement(_DatasetContext.DatasetProvider, props, /*#__PURE__*/_react.default.createElement("div", {
|
|
70
68
|
className: "row g-0"
|
|
71
69
|
}, /*#__PURE__*/_react.default.createElement("div", {
|
|
72
|
-
className: "cherita-app-obs"
|
|
70
|
+
className: "cherita-app-obs modern-scrollbars border-end h-100"
|
|
73
71
|
}, /*#__PURE__*/_react.default.createElement(_ObsList.ObsColsList, null)), /*#__PURE__*/_react.default.createElement("div", {
|
|
74
72
|
className: "cherita-app-plot"
|
|
75
73
|
}, /*#__PURE__*/_react.default.createElement("div", {
|
|
@@ -126,27 +124,6 @@ function FullPage({
|
|
|
126
124
|
function FullPageScatterplot(props) {
|
|
127
125
|
return /*#__PURE__*/_react.default.createElement(FullPage, props, /*#__PURE__*/_react.default.createElement(_Scatterplot.Scatterplot, null));
|
|
128
126
|
}
|
|
129
|
-
function FullPagePseudospatial(props) {
|
|
130
|
-
return /*#__PURE__*/_react.default.createElement(FullPage, props, /*#__PURE__*/_react.default.createElement("div", {
|
|
131
|
-
className: "container-fluid h-100"
|
|
132
|
-
}, /*#__PURE__*/_react.default.createElement("div", {
|
|
133
|
-
className: "row"
|
|
134
|
-
}, /*#__PURE__*/_react.default.createElement("div", {
|
|
135
|
-
className: "col-12 col-lg-7"
|
|
136
|
-
}, /*#__PURE__*/_react.default.createElement(_Scatterplot.Scatterplot, null)), /*#__PURE__*/_react.default.createElement("div", {
|
|
137
|
-
className: "col-12 col-lg-5"
|
|
138
|
-
}, /*#__PURE__*/_react.default.createElement("div", {
|
|
139
|
-
className: "container-fluid h-100 d-flex align-itemms-center justify-content-center"
|
|
140
|
-
}, /*#__PURE__*/_react.default.createElement("div", {
|
|
141
|
-
className: "row w-100 py-3"
|
|
142
|
-
}, /*#__PURE__*/_react.default.createElement("div", {
|
|
143
|
-
className: "col-12"
|
|
144
|
-
}, /*#__PURE__*/_react.default.createElement("div", {
|
|
145
|
-
className: "p-2"
|
|
146
|
-
}, /*#__PURE__*/_react.default.createElement(_Pseudospatial.Pseudospatial, null))), /*#__PURE__*/_react.default.createElement("div", {
|
|
147
|
-
className: "col-12"
|
|
148
|
-
}, /*#__PURE__*/_react.default.createElement(_Pseudospatial.PseudospatialImage, null))))))));
|
|
149
|
-
}
|
|
150
127
|
function FullPagePlots(props) {
|
|
151
128
|
return /*#__PURE__*/_react.default.createElement(FullPage, _extends({}, props, {
|
|
152
129
|
varMode: _constants.SELECTION_MODES.MULTIPLE
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.FullPage = FullPage;
|
|
7
|
+
exports.FullPagePseudospatial = FullPagePseudospatial;
|
|
8
|
+
var _react = _interopRequireWildcard(require("react"));
|
|
9
|
+
var _freeSolidSvgIcons = require("@fortawesome/free-solid-svg-icons");
|
|
10
|
+
var _reactFontawesome = require("@fortawesome/react-fontawesome");
|
|
11
|
+
var _reactBootstrap = require("react-bootstrap");
|
|
12
|
+
var _constants = require("../../constants/constants");
|
|
13
|
+
var _DatasetContext = require("../../context/DatasetContext");
|
|
14
|
+
var _ObsList = require("../obs-list/ObsList");
|
|
15
|
+
var _offcanvas = require("../offcanvas");
|
|
16
|
+
var _Pseudospatial = require("../pseudospatial/Pseudospatial");
|
|
17
|
+
var _PseudospatialToolbar = require("../pseudospatial/PseudospatialToolbar");
|
|
18
|
+
var _Scatterplot = require("../scatterplot/Scatterplot");
|
|
19
|
+
var _ScatterplotControls = require("../scatterplot/ScatterplotControls");
|
|
20
|
+
var _SearchBar = require("../search-bar/SearchBar");
|
|
21
|
+
var _VarList = require("../var-list/VarList");
|
|
22
|
+
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); }
|
|
23
|
+
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; }
|
|
24
|
+
function FullPage({
|
|
25
|
+
children,
|
|
26
|
+
varMode = _constants.SELECTION_MODES.SINGLE,
|
|
27
|
+
...props
|
|
28
|
+
}) {
|
|
29
|
+
const appRef = (0, _react.useRef)();
|
|
30
|
+
const [appDimensions, setAppDimensions] = (0, _react.useState)({
|
|
31
|
+
width: 0,
|
|
32
|
+
height: 0
|
|
33
|
+
});
|
|
34
|
+
const [showObs, setShowObs] = (0, _react.useState)(false);
|
|
35
|
+
const [showObsm, setShowObsm] = (0, _react.useState)(false);
|
|
36
|
+
const [showVars, setShowVars] = (0, _react.useState)(false);
|
|
37
|
+
const [showControls, setShowControls] = (0, _react.useState)(false);
|
|
38
|
+
const [showPseudospatialControls, setShowPseudospatialControls] = (0, _react.useState)(false);
|
|
39
|
+
const [showModal, setShowModal] = (0, _react.useState)(false);
|
|
40
|
+
const [pseudospatialPlotType, setpseudospatialPlotType] = (0, _react.useState)(null);
|
|
41
|
+
(0, _react.useEffect)(() => {
|
|
42
|
+
const updateDimensions = () => {
|
|
43
|
+
if (appRef.current) {
|
|
44
|
+
// Get the distance from the top of the page to the target element
|
|
45
|
+
const rect = appRef.current.getBoundingClientRect();
|
|
46
|
+
const distanceFromTop = rect.top + window.scrollY;
|
|
47
|
+
|
|
48
|
+
// Calculate the available height for the Cherita app
|
|
49
|
+
const availableHeight = window.innerHeight - distanceFromTop;
|
|
50
|
+
|
|
51
|
+
// Update the dimensions to fit the viewport minus the navbar height
|
|
52
|
+
setAppDimensions({
|
|
53
|
+
width: appRef.current.offsetWidth,
|
|
54
|
+
height: availableHeight
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
window.addEventListener("resize", updateDimensions);
|
|
59
|
+
updateDimensions(); // Initial update
|
|
60
|
+
return () => window.removeEventListener("resize", updateDimensions);
|
|
61
|
+
}, []);
|
|
62
|
+
return /*#__PURE__*/_react.default.createElement("div", {
|
|
63
|
+
ref: appRef,
|
|
64
|
+
className: "cherita-app",
|
|
65
|
+
style: {
|
|
66
|
+
height: appDimensions.height
|
|
67
|
+
}
|
|
68
|
+
}, /*#__PURE__*/_react.default.createElement(_DatasetContext.DatasetProvider, props, /*#__PURE__*/_react.default.createElement(_reactBootstrap.Container, {
|
|
69
|
+
fluid: true,
|
|
70
|
+
className: "d-flex g-0",
|
|
71
|
+
style: {
|
|
72
|
+
height: appDimensions.height
|
|
73
|
+
}
|
|
74
|
+
}, /*#__PURE__*/_react.default.createElement(_reactBootstrap.Navbar, {
|
|
75
|
+
expand: "sm",
|
|
76
|
+
bg: "primary",
|
|
77
|
+
className: "cherita-navbar"
|
|
78
|
+
}, /*#__PURE__*/_react.default.createElement("div", {
|
|
79
|
+
className: "container-fluid"
|
|
80
|
+
}, /*#__PURE__*/_react.default.createElement(_reactBootstrap.Navbar.Toggle, {
|
|
81
|
+
"aria-controls": "navbarScroll"
|
|
82
|
+
}), /*#__PURE__*/_react.default.createElement(_reactBootstrap.Navbar.Collapse, {
|
|
83
|
+
id: "navbarScroll"
|
|
84
|
+
}, /*#__PURE__*/_react.default.createElement(_reactBootstrap.Nav, {
|
|
85
|
+
className: "me-auto my-0",
|
|
86
|
+
navbarScroll: true
|
|
87
|
+
}, /*#__PURE__*/_react.default.createElement(_reactBootstrap.Nav.Item, {
|
|
88
|
+
className: "d-block d-lg-none"
|
|
89
|
+
}, /*#__PURE__*/_react.default.createElement(_reactBootstrap.Nav.Link, {
|
|
90
|
+
onClick: () => setShowObs(true)
|
|
91
|
+
}, "Observations")), /*#__PURE__*/_react.default.createElement(_reactBootstrap.Nav.Item, null, /*#__PURE__*/_react.default.createElement(_reactBootstrap.Nav.Link, {
|
|
92
|
+
onClick: () => setShowVars(true)
|
|
93
|
+
}, "Features"))), /*#__PURE__*/_react.default.createElement(_reactBootstrap.Nav, {
|
|
94
|
+
className: "d-flex"
|
|
95
|
+
}, /*#__PURE__*/_react.default.createElement(_reactBootstrap.Nav.Item, null, /*#__PURE__*/_react.default.createElement(_reactBootstrap.Nav.Link, {
|
|
96
|
+
onClick: () => setShowControls(true)
|
|
97
|
+
}, "Controls")))))), /*#__PURE__*/_react.default.createElement("div", {
|
|
98
|
+
className: "cherita-app-obs modern-scrollbars border-end h-100"
|
|
99
|
+
}, /*#__PURE__*/_react.default.createElement(_ObsList.ObsColsList, null)), /*#__PURE__*/_react.default.createElement("div", {
|
|
100
|
+
className: "cherita-app-canvas flex-grow-1"
|
|
101
|
+
}, children), /*#__PURE__*/_react.default.createElement("div", {
|
|
102
|
+
className: "cherita-app-sidebar p-3"
|
|
103
|
+
}, /*#__PURE__*/_react.default.createElement(_reactBootstrap.Card, null, /*#__PURE__*/_react.default.createElement(_reactBootstrap.Card.Header, {
|
|
104
|
+
className: "d-flex justify-content-evenly align-items-center"
|
|
105
|
+
}, /*#__PURE__*/_react.default.createElement(_reactBootstrap.Button, {
|
|
106
|
+
variant: "link",
|
|
107
|
+
onClick: () => setShowModal(true)
|
|
108
|
+
}, /*#__PURE__*/_react.default.createElement(_reactFontawesome.FontAwesomeIcon, {
|
|
109
|
+
icon: _freeSolidSvgIcons.faArrowUpRightFromSquare
|
|
110
|
+
}))), /*#__PURE__*/_react.default.createElement(_reactBootstrap.Card.Body, {
|
|
111
|
+
className: "d-flex flex-column p-0"
|
|
112
|
+
}, /*#__PURE__*/_react.default.createElement("div", {
|
|
113
|
+
className: "sidebar-pseudospatial"
|
|
114
|
+
}, /*#__PURE__*/_react.default.createElement(_Pseudospatial.Pseudospatial, {
|
|
115
|
+
className: "sidebar-pseudospatial",
|
|
116
|
+
plotType: pseudospatialPlotType,
|
|
117
|
+
setPlotType: setpseudospatialPlotType,
|
|
118
|
+
setShowControls: setShowPseudospatialControls
|
|
119
|
+
})), /*#__PURE__*/_react.default.createElement("div", {
|
|
120
|
+
className: "sidebar-features modern-scrollbars"
|
|
121
|
+
}, /*#__PURE__*/_react.default.createElement(_SearchBar.SearchBar, {
|
|
122
|
+
searchDiseases: true,
|
|
123
|
+
searchVar: true
|
|
124
|
+
}), /*#__PURE__*/_react.default.createElement(_VarList.VarNamesList, {
|
|
125
|
+
mode: varMode
|
|
126
|
+
})))))), /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement(_reactBootstrap.Modal, {
|
|
127
|
+
show: showModal,
|
|
128
|
+
onHide: () => setShowModal(false),
|
|
129
|
+
centered: true
|
|
130
|
+
}, /*#__PURE__*/_react.default.createElement(_reactBootstrap.Modal.Header, {
|
|
131
|
+
closeButton: true
|
|
132
|
+
}), /*#__PURE__*/_react.default.createElement(_reactBootstrap.Modal.Body, null, /*#__PURE__*/_react.default.createElement(_Pseudospatial.Pseudospatial, {
|
|
133
|
+
plotType: pseudospatialPlotType,
|
|
134
|
+
setPlotType: setpseudospatialPlotType,
|
|
135
|
+
setShowControls: setShowPseudospatialControls,
|
|
136
|
+
height: 500
|
|
137
|
+
}))), /*#__PURE__*/_react.default.createElement(_offcanvas.OffcanvasObs, {
|
|
138
|
+
show: showObs,
|
|
139
|
+
handleClose: () => setShowObs(false)
|
|
140
|
+
}), /*#__PURE__*/_react.default.createElement(_offcanvas.OffcanvasVars, {
|
|
141
|
+
show: showVars,
|
|
142
|
+
handleClose: () => setShowVars(false)
|
|
143
|
+
}), /*#__PURE__*/_react.default.createElement(_offcanvas.OffcanvasControls, {
|
|
144
|
+
show: showControls,
|
|
145
|
+
handleClose: () => setShowControls(false),
|
|
146
|
+
Controls: _ScatterplotControls.ScatterplotControls
|
|
147
|
+
}), /*#__PURE__*/_react.default.createElement(_offcanvas.OffcanvasControls, {
|
|
148
|
+
show: showPseudospatialControls,
|
|
149
|
+
handleClose: () => setShowPseudospatialControls(false),
|
|
150
|
+
Controls: _PseudospatialToolbar.PseudospatialToolbar,
|
|
151
|
+
plotType: pseudospatialPlotType
|
|
152
|
+
}), /*#__PURE__*/_react.default.createElement(_offcanvas.OffcanvasObsm, {
|
|
153
|
+
show: showObsm,
|
|
154
|
+
handleClose: () => setShowObsm(false)
|
|
155
|
+
}))));
|
|
156
|
+
}
|
|
157
|
+
function FullPagePseudospatial(props) {
|
|
158
|
+
return /*#__PURE__*/_react.default.createElement(FullPage, props, /*#__PURE__*/_react.default.createElement(_Scatterplot.Scatterplot, null));
|
|
159
|
+
}
|
|
@@ -20,6 +20,7 @@ var _LoadingIndicators = require("../../utils/LoadingIndicators");
|
|
|
20
20
|
var _requests = require("../../utils/requests");
|
|
21
21
|
var _string = require("../../utils/string");
|
|
22
22
|
var _VirtualizedList = require("../../utils/VirtualizedList");
|
|
23
|
+
var _zarrData = require("../../utils/zarrData");
|
|
23
24
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
24
25
|
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); }
|
|
25
26
|
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; }
|
|
@@ -79,12 +80,55 @@ const useObsHistogram = obs => {
|
|
|
79
80
|
refetchOnMount: false
|
|
80
81
|
});
|
|
81
82
|
};
|
|
83
|
+
const getBinIndex = (v, binEdges) => {
|
|
84
|
+
const EPSILON = 1e-6;
|
|
85
|
+
const lastEdge = _lodash.default.last(binEdges);
|
|
86
|
+
const allButLastEdges = _lodash.default.initial(binEdges);
|
|
87
|
+
const modifiedBinEdges = [...allButLastEdges, [lastEdge[0], lastEdge[1] + EPSILON]];
|
|
88
|
+
return _lodash.default.findIndex(modifiedBinEdges, range => _lodash.default.inRange(v, ...range));
|
|
89
|
+
};
|
|
90
|
+
const useFilteredObsData = obs => {
|
|
91
|
+
const {
|
|
92
|
+
obsIndices
|
|
93
|
+
} = (0, _FilterContext.useFilteredData)();
|
|
94
|
+
const obsData = (0, _zarrData.useObsData)(obs);
|
|
95
|
+
const isCategorical = obs.type === _constants.OBS_TYPES.CATEGORICAL || obs.type === _constants.OBS_TYPES.BOOLEAN;
|
|
96
|
+
const {
|
|
97
|
+
valueCounts,
|
|
98
|
+
pct
|
|
99
|
+
} = (0, _react.useMemo)(() => {
|
|
100
|
+
const filteredObsValues = _lodash.default.at(obsData.data, [...(obsIndices || [])]);
|
|
101
|
+
let valueCounts = {};
|
|
102
|
+
if (isCategorical) {
|
|
103
|
+
valueCounts = _lodash.default.countBy(filteredObsValues);
|
|
104
|
+
} else {
|
|
105
|
+
valueCounts = _lodash.default.countBy(filteredObsValues, v => {
|
|
106
|
+
return getBinIndex(v, obs.bins?.binEdges || [[null, null]]);
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
valueCounts = _lodash.default.mapKeys(valueCounts, (_v, i) => {
|
|
110
|
+
return obs.codesMap[i];
|
|
111
|
+
});
|
|
112
|
+
const totalCounts = obsIndices?.size;
|
|
113
|
+
const pct = _lodash.default.mapValues(valueCounts, v => v / totalCounts * 100);
|
|
114
|
+
return {
|
|
115
|
+
valueCounts,
|
|
116
|
+
pct
|
|
117
|
+
};
|
|
118
|
+
}, [isCategorical, obs.bins?.binEdges, obs.codesMap, obsData.data, obsIndices]);
|
|
119
|
+
return {
|
|
120
|
+
value_counts: valueCounts,
|
|
121
|
+
pct: pct
|
|
122
|
+
};
|
|
123
|
+
};
|
|
82
124
|
function CategoricalItem({
|
|
83
125
|
value,
|
|
84
126
|
label,
|
|
85
127
|
code,
|
|
86
|
-
|
|
87
|
-
|
|
128
|
+
stats = {
|
|
129
|
+
value_counts: null,
|
|
130
|
+
pct: null
|
|
131
|
+
},
|
|
88
132
|
isOmitted,
|
|
89
133
|
min,
|
|
90
134
|
max,
|
|
@@ -94,6 +138,11 @@ function CategoricalItem({
|
|
|
94
138
|
isPending: false,
|
|
95
139
|
altColor: false
|
|
96
140
|
},
|
|
141
|
+
filteredStats = {
|
|
142
|
+
value_counts: null,
|
|
143
|
+
pct: null
|
|
144
|
+
},
|
|
145
|
+
isSliced,
|
|
97
146
|
showColor = true
|
|
98
147
|
}) {
|
|
99
148
|
const {
|
|
@@ -114,27 +163,49 @@ function CategoricalItem({
|
|
|
114
163
|
onChange: () => onChange(value)
|
|
115
164
|
})), /*#__PURE__*/_react.default.createElement("div", {
|
|
116
165
|
className: "d-flex align-items-center"
|
|
166
|
+
}, /*#__PURE__*/_react.default.createElement("div", {
|
|
167
|
+
className: "pl-1 m-0 flex-grow-1"
|
|
117
168
|
}, /*#__PURE__*/_react.default.createElement(_Histogram.Histogram, {
|
|
118
169
|
data: histogramData.data,
|
|
119
170
|
isPending: histogramData.isPending,
|
|
120
171
|
altColor: histogramData.altColor
|
|
121
|
-
}), /*#__PURE__*/_react.default.createElement("div", {
|
|
172
|
+
})), /*#__PURE__*/_react.default.createElement("div", {
|
|
122
173
|
className: "pl-1 m-0"
|
|
123
174
|
}, /*#__PURE__*/_react.default.createElement(_material.Tooltip, {
|
|
124
|
-
title: `${(0, _string.formatNumerical)(pct, _string.FORMATS.EXPONENTIAL)}%`,
|
|
175
|
+
title: isSliced ? /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, "Filtered:", " ", (0, _string.formatNumerical)(filteredStats.pct, _string.FORMATS.EXPONENTIAL), "%", /*#__PURE__*/_react.default.createElement("br", null), "Total: ", (0, _string.formatNumerical)(stats.pct, _string.FORMATS.EXPONENTIAL), "%") : `${(0, _string.formatNumerical)(stats.pct, _string.FORMATS.EXPONENTIAL)}%`,
|
|
125
176
|
placement: "left",
|
|
126
177
|
arrow: true
|
|
127
178
|
}, /*#__PURE__*/_react.default.createElement("div", {
|
|
128
179
|
className: "d-flex align-items-center"
|
|
129
180
|
}, /*#__PURE__*/_react.default.createElement(_reactBootstrap.Badge, {
|
|
130
|
-
className: "value-count-badge"
|
|
131
|
-
|
|
132
|
-
fontWeight: "lighter"
|
|
133
|
-
}
|
|
134
|
-
}, (0, _string.formatNumerical)(parseInt(value_counts), _string.FORMATS.EXPONENTIAL)), /*#__PURE__*/_react.default.createElement("div", {
|
|
181
|
+
className: "value-count-badge"
|
|
182
|
+
}, " ", isSliced && /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, (0, _string.formatNumerical)(parseInt(filteredStats.value_counts)), " ", "out of", " "), (0, _string.formatNumerical)(parseInt(stats.value_counts), _string.FORMATS.EXPONENTIAL)), /*#__PURE__*/_react.default.createElement("div", {
|
|
135
183
|
className: "value-pct-gauge-container"
|
|
136
|
-
}, /*#__PURE__*/_react.default.createElement(_xCharts.Gauge, {
|
|
137
|
-
|
|
184
|
+
}, isSliced ? /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_xCharts.Gauge, {
|
|
185
|
+
className: "pct-gauge filtered-pct-gauge",
|
|
186
|
+
value: filteredStats.pct,
|
|
187
|
+
text: null,
|
|
188
|
+
innerRadius: "50%",
|
|
189
|
+
outerRadius: "75%",
|
|
190
|
+
margin: {
|
|
191
|
+
top: 0,
|
|
192
|
+
right: 0,
|
|
193
|
+
bottom: 0,
|
|
194
|
+
left: 0
|
|
195
|
+
}
|
|
196
|
+
}), /*#__PURE__*/_react.default.createElement(_xCharts.Gauge, {
|
|
197
|
+
className: "pct-gauge",
|
|
198
|
+
value: stats.pct,
|
|
199
|
+
text: null,
|
|
200
|
+
innerRadius: "75%",
|
|
201
|
+
margin: {
|
|
202
|
+
top: 0,
|
|
203
|
+
right: 0,
|
|
204
|
+
bottom: 0,
|
|
205
|
+
left: 0
|
|
206
|
+
}
|
|
207
|
+
})) : /*#__PURE__*/_react.default.createElement(_xCharts.Gauge, {
|
|
208
|
+
value: stats.pct,
|
|
138
209
|
text: null,
|
|
139
210
|
innerRadius: "50%",
|
|
140
211
|
margin: {
|
|
@@ -186,6 +257,7 @@ function CategoricalObs({
|
|
|
186
257
|
const min = _lodash.default.min(_lodash.default.values(obs.codes));
|
|
187
258
|
const max = _lodash.default.max(_lodash.default.values(obs.codes));
|
|
188
259
|
const obsHistograms = useObsHistogram(obs);
|
|
260
|
+
const filteredObsData = useFilteredObsData(obs);
|
|
189
261
|
(0, _react.useEffect)(() => {
|
|
190
262
|
if (dataset.selectedObs?.name === obs.name) {
|
|
191
263
|
const selectedObsData = _lodash.default.omit(dataset.selectedObs, ["omit"]);
|
|
@@ -208,8 +280,10 @@ function CategoricalObs({
|
|
|
208
280
|
return {
|
|
209
281
|
value: obs.values[index],
|
|
210
282
|
code: obs.codes[obs.values[index]],
|
|
211
|
-
|
|
212
|
-
|
|
283
|
+
stats: {
|
|
284
|
+
value_counts: obs.value_counts[obs.values[index]],
|
|
285
|
+
pct: obs.value_counts[obs.values[index]] / totalCounts * 100
|
|
286
|
+
},
|
|
213
287
|
isOmitted: _lodash.default.includes(obs.omit, obs.codes[obs.values[index]]),
|
|
214
288
|
label: obs.values[index],
|
|
215
289
|
histogramData: dataset.colorEncoding === _constants.COLOR_ENCODINGS.VAR ? {
|
|
@@ -219,11 +293,18 @@ function CategoricalObs({
|
|
|
219
293
|
} : {
|
|
220
294
|
data: null,
|
|
221
295
|
isPending: false
|
|
222
|
-
}
|
|
296
|
+
},
|
|
297
|
+
filteredStats: {
|
|
298
|
+
value_counts: filteredObsData?.value_counts[obs.values[index]] || 0,
|
|
299
|
+
pct: filteredObsData?.pct[obs.values[index]] || 0
|
|
300
|
+
},
|
|
301
|
+
isSliced: isSliced
|
|
223
302
|
};
|
|
224
|
-
}, [dataset.colorEncoding, isSliced, obs.codes, obs.omit, obs.value_counts, obs.values, obsHistograms.fetchedData, obsHistograms.isPending, totalCounts]);
|
|
303
|
+
}, [dataset.colorEncoding, filteredObsData?.pct, filteredObsData?.value_counts, isSliced, obs.codes, obs.omit, obs.value_counts, obs.values, obsHistograms.fetchedData, obsHistograms.isPending, totalCounts]);
|
|
225
304
|
showColor &= dataset.colorEncoding === _constants.COLOR_ENCODINGS.OBS;
|
|
226
|
-
return /*#__PURE__*/_react.default.createElement(_reactBootstrap.ListGroup,
|
|
305
|
+
return /*#__PURE__*/_react.default.createElement(_reactBootstrap.ListGroup, {
|
|
306
|
+
variant: "flush"
|
|
307
|
+
}, /*#__PURE__*/_react.default.createElement(_reactBootstrap.ListGroup.Item, null, /*#__PURE__*/_react.default.createElement(_ObsToolbar.ObsToolbar, {
|
|
227
308
|
item: obs,
|
|
228
309
|
onToggleAllObs: toggleAll,
|
|
229
310
|
onToggleLabel: toggleLabel,
|
|
@@ -310,6 +391,9 @@ function ContinuousObs({
|
|
|
310
391
|
}) {
|
|
311
392
|
const ENDPOINT = "obs/bins";
|
|
312
393
|
const dataset = (0, _DatasetContext.useDataset)();
|
|
394
|
+
const {
|
|
395
|
+
isSliced
|
|
396
|
+
} = (0, _FilterContext.useFilteredData)();
|
|
313
397
|
const dispatch = (0, _DatasetContext.useDatasetDispatch)();
|
|
314
398
|
const binnedObs = binContinuous(obs, _lodash.default.min([N_BINS, obs.n_unique]));
|
|
315
399
|
const params = {
|
|
@@ -325,6 +409,7 @@ function ContinuousObs({
|
|
|
325
409
|
} = (0, _requests.useFetch)(ENDPOINT, params, {
|
|
326
410
|
refetchOnMount: false
|
|
327
411
|
});
|
|
412
|
+
const filteredObsData = useFilteredObsData(obs);
|
|
328
413
|
const updatedObs = fetchedData && _lodash.default.isMatch(obs, fetchedData);
|
|
329
414
|
(0, _react.useEffect)(() => {
|
|
330
415
|
// Update ObsList obsCols with bin data
|
|
@@ -362,13 +447,22 @@ function ContinuousObs({
|
|
|
362
447
|
return {
|
|
363
448
|
value: obs.values[index],
|
|
364
449
|
code: obs.codes[obs.values[index]],
|
|
365
|
-
|
|
366
|
-
|
|
450
|
+
stats: {
|
|
451
|
+
value_counts: obs.value_counts[obs.values[index]],
|
|
452
|
+
pct: obs.value_counts[obs.values[index]] / totalCounts * 100
|
|
453
|
+
},
|
|
367
454
|
isOmitted: _lodash.default.includes(obs.omit, obs.codes[obs.values[index]]),
|
|
368
|
-
label: isNaN(obs.values[index]) ? "NaN" : getContinuousLabel(obs.codes[obs.values[index]], obs.bins.binEdges)
|
|
455
|
+
label: isNaN(obs.values[index]) ? "NaN" : getContinuousLabel(obs.codes[obs.values[index]], obs.bins.binEdges),
|
|
456
|
+
filteredStats: {
|
|
457
|
+
value_counts: filteredObsData?.value_counts[obs.values[index]] || 0,
|
|
458
|
+
pct: filteredObsData?.pct[obs.values[index]] || 0
|
|
459
|
+
},
|
|
460
|
+
isSliced: isSliced
|
|
369
461
|
};
|
|
370
462
|
};
|
|
371
|
-
return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, isPending && /*#__PURE__*/_react.default.createElement(_LoadingIndicators.LoadingLinear, null), !serverError && updatedObs && /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_reactBootstrap.ListGroup,
|
|
463
|
+
return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, isPending && /*#__PURE__*/_react.default.createElement(_LoadingIndicators.LoadingLinear, null), !serverError && updatedObs && /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_reactBootstrap.ListGroup, {
|
|
464
|
+
variant: "flush"
|
|
465
|
+
}, /*#__PURE__*/_react.default.createElement(_reactBootstrap.ListGroup.Item, null, /*#__PURE__*/_react.default.createElement(_ObsToolbar.ObsToolbar, {
|
|
372
466
|
item: obs,
|
|
373
467
|
onToggleAllObs: toggleAll,
|
|
374
468
|
onToggleLabel: toggleLabel,
|
|
@@ -5,8 +5,13 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.ObsColsList = ObsColsList;
|
|
7
7
|
var _react = _interopRequireWildcard(require("react"));
|
|
8
|
+
var _freeSolidSvgIcons = require("@fortawesome/free-solid-svg-icons");
|
|
9
|
+
var _reactFontawesome = require("@fortawesome/react-fontawesome");
|
|
8
10
|
var _lodash = _interopRequireDefault(require("lodash"));
|
|
9
11
|
var _reactBootstrap = require("react-bootstrap");
|
|
12
|
+
var _Accordion = _interopRequireDefault(require("react-bootstrap/Accordion"));
|
|
13
|
+
var _AccordionButton = require("react-bootstrap/AccordionButton");
|
|
14
|
+
var _AccordionContext = _interopRequireDefault(require("react-bootstrap/AccordionContext"));
|
|
10
15
|
var _ObsItem = require("./ObsItem");
|
|
11
16
|
var _constants = require("../../constants/constants");
|
|
12
17
|
var _DatasetContext = require("../../context/DatasetContext");
|
|
@@ -173,17 +178,56 @@ function ObsColsList({
|
|
|
173
178
|
});
|
|
174
179
|
}
|
|
175
180
|
};
|
|
176
|
-
|
|
181
|
+
function ObsAccordionToggle({
|
|
182
|
+
children,
|
|
183
|
+
eventKey
|
|
184
|
+
}) {
|
|
185
|
+
const {
|
|
186
|
+
activeEventKey
|
|
187
|
+
} = (0, _react.useContext)(_AccordionContext.default);
|
|
188
|
+
const decoratedOnClick = (0, _AccordionButton.useAccordionButton)(eventKey, () => {
|
|
189
|
+
handleAccordionToggle(eventKey);
|
|
190
|
+
});
|
|
191
|
+
const isCurrentEventKey = Array.isArray(activeEventKey) ? activeEventKey.includes(eventKey) : activeEventKey === eventKey;
|
|
192
|
+
return /*#__PURE__*/_react.default.createElement("div", {
|
|
193
|
+
className: `obs-accordion-header ${isCurrentEventKey ? "active" : ""}`,
|
|
194
|
+
onClick: decoratedOnClick
|
|
195
|
+
}, /*#__PURE__*/_react.default.createElement("span", {
|
|
196
|
+
className: "obs-accordion-header-chevron"
|
|
197
|
+
}, /*#__PURE__*/_react.default.createElement(_reactFontawesome.FontAwesomeIcon, {
|
|
198
|
+
icon: isCurrentEventKey ? _freeSolidSvgIcons.faChevronDown : _freeSolidSvgIcons.faChevronRight
|
|
199
|
+
})), /*#__PURE__*/_react.default.createElement("span", {
|
|
200
|
+
className: "obs-accordion-header-title"
|
|
201
|
+
}, children));
|
|
202
|
+
}
|
|
203
|
+
const obsList = _lodash.default.map(obsCols, (item, index) => {
|
|
177
204
|
if (item.type === _constants.OBS_TYPES.DISCRETE) {
|
|
178
205
|
return null;
|
|
179
206
|
}
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
207
|
+
const inLabelObs = _lodash.default.some(dataset.labelObs, i => i.name === item.name);
|
|
208
|
+
const inSliceObs = dataset.sliceBy.obs && dataset.selectedObs?.name === item.name;
|
|
209
|
+
const isColorEncoding = dataset.colorEncoding === _constants.COLOR_ENCODINGS.OBS && dataset.selectedObs?.name === item.name;
|
|
210
|
+
return /*#__PURE__*/_react.default.createElement("div", {
|
|
211
|
+
key: item.name
|
|
212
|
+
}, /*#__PURE__*/_react.default.createElement(ObsAccordionToggle, {
|
|
213
|
+
eventKey: item.name
|
|
214
|
+
}, /*#__PURE__*/_react.default.createElement("div", null, item.name), /*#__PURE__*/_react.default.createElement("div", null, inLabelObs && /*#__PURE__*/_react.default.createElement(_reactFontawesome.FontAwesomeIcon, {
|
|
215
|
+
className: "mx-1",
|
|
216
|
+
icon: _freeSolidSvgIcons.faListOl,
|
|
217
|
+
title: "In tooltip"
|
|
218
|
+
}), inSliceObs && /*#__PURE__*/_react.default.createElement(_reactFontawesome.FontAwesomeIcon, {
|
|
219
|
+
className: "mx-1",
|
|
220
|
+
icon: _freeSolidSvgIcons.faScissors,
|
|
221
|
+
title: "Filter applied"
|
|
222
|
+
}), isColorEncoding && /*#__PURE__*/_react.default.createElement(_reactFontawesome.FontAwesomeIcon, {
|
|
223
|
+
className: "mx-1",
|
|
224
|
+
icon: _freeSolidSvgIcons.faDroplet,
|
|
225
|
+
title: "Is color encoding"
|
|
226
|
+
}))), /*#__PURE__*/_react.default.createElement(_Accordion.default.Collapse, {
|
|
227
|
+
eventKey: item.name
|
|
228
|
+
}, /*#__PURE__*/_react.default.createElement("div", {
|
|
229
|
+
className: "obs-accordion-body"
|
|
230
|
+
}, expandedItems[item.name] && (item.type === _constants.OBS_TYPES.CATEGORICAL || item.type === _constants.OBS_TYPES.BOOLEAN ? /*#__PURE__*/_react.default.createElement(_ObsItem.CategoricalObs, {
|
|
187
231
|
key: item.name,
|
|
188
232
|
obs: item,
|
|
189
233
|
updateObs: updateObs,
|
|
@@ -202,18 +246,15 @@ function ObsColsList({
|
|
|
202
246
|
toggleLabel: () => toggleLabel(item),
|
|
203
247
|
toggleSlice: () => toggleSlice(item),
|
|
204
248
|
toggleColor: () => toggleColor(item)
|
|
205
|
-
}))));
|
|
249
|
+
})))));
|
|
206
250
|
});
|
|
207
251
|
if (!serverError) {
|
|
208
|
-
return /*#__PURE__*/_react.default.createElement("div", {
|
|
209
|
-
className: "position-relative h-100"
|
|
210
|
-
}, /*#__PURE__*/_react.default.createElement("div", {
|
|
211
|
-
className: "list-group overflow-auto h-100"
|
|
212
|
-
}, isPending && /*#__PURE__*/_react.default.createElement(_LoadingIndicators.LoadingSpinner, null), /*#__PURE__*/_react.default.createElement(_reactBootstrap.Accordion, {
|
|
252
|
+
return /*#__PURE__*/_react.default.createElement("div", null, isPending && /*#__PURE__*/_react.default.createElement(_LoadingIndicators.LoadingSpinner, null), /*#__PURE__*/_react.default.createElement(_Accordion.default, {
|
|
213
253
|
flush: true,
|
|
214
254
|
defaultActiveKey: [active],
|
|
215
|
-
alwaysOpen: true
|
|
216
|
-
|
|
255
|
+
alwaysOpen: true,
|
|
256
|
+
className: "obs-accordion"
|
|
257
|
+
}, obsList));
|
|
217
258
|
} else {
|
|
218
259
|
return /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement(_reactBootstrap.Alert, {
|
|
219
260
|
variant: "danger"
|
|
@@ -29,7 +29,7 @@ function ObsToolbar({
|
|
|
29
29
|
const inSliceObs = dataset.sliceBy.obs && dataset.selectedObs?.name === item.name;
|
|
30
30
|
const isColorEncoding = dataset.colorEncoding === _constants.COLOR_ENCODINGS.OBS && dataset.selectedObs?.name === item.name;
|
|
31
31
|
return /*#__PURE__*/_react.default.createElement("div", {
|
|
32
|
-
className: "d-flex"
|
|
32
|
+
className: "d-flex align-items-center"
|
|
33
33
|
}, /*#__PURE__*/_react.default.createElement("div", {
|
|
34
34
|
className: "flex-grow-1"
|
|
35
35
|
}, showToggleAllObs && /*#__PURE__*/_react.default.createElement(_reactBootstrap.Form.Check, {
|
|
@@ -45,14 +45,14 @@ function ObsToolbar({
|
|
|
45
45
|
onClick: onToggleLabel,
|
|
46
46
|
title: "Add to tooltip"
|
|
47
47
|
}, /*#__PURE__*/_react.default.createElement(_reactFontawesome.FontAwesomeIcon, {
|
|
48
|
-
icon: _freeSolidSvgIcons.
|
|
48
|
+
icon: _freeSolidSvgIcons.faListOl
|
|
49
49
|
})), showSlice && /*#__PURE__*/_react.default.createElement(_reactBootstrap.Button, {
|
|
50
50
|
variant: inSliceObs ? "primary" : "outline-primary",
|
|
51
51
|
size: "sm",
|
|
52
52
|
onClick: onToggleSlice,
|
|
53
|
-
title: "
|
|
53
|
+
title: "Filter to selected"
|
|
54
54
|
}, /*#__PURE__*/_react.default.createElement(_reactFontawesome.FontAwesomeIcon, {
|
|
55
|
-
icon: _freeSolidSvgIcons.
|
|
55
|
+
icon: _freeSolidSvgIcons.faScissors
|
|
56
56
|
})), showColor && /*#__PURE__*/_react.default.createElement(_reactBootstrap.Button, {
|
|
57
57
|
variant: isColorEncoding ? "primary" : "outline-primary",
|
|
58
58
|
size: "sm",
|