@haniffalab/cherita-react 0.2.0-dev.2024-05-09.07fb18ed → 0.2.0-dev.2024-05-22.5ce64346

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/App.scss CHANGED
@@ -14,7 +14,7 @@
14
14
 
15
15
  .cherita-navbar {
16
16
  position: absolute;
17
- z-index: 10;
17
+ z-index: 11;
18
18
  top: 20px;
19
19
  right: 20px;
20
20
  left: 20px;
@@ -59,20 +59,41 @@
59
59
 
60
60
  .cherita-container-scatterplot {
61
61
  position: relative;
62
- min-height: 500px;
62
+ min-height: 300px;
63
+ height: 100%;
63
64
  }
64
65
 
65
66
  .cherita-toolbox {
66
67
  position: absolute;
67
68
  z-index: 10;
68
69
  bottom: 20px;
69
- right: 20px;
70
+ left: 20px;
71
+ }
72
+ .cherita-spatial-controls {
73
+ position: absolute;
74
+ z-index: 10;
75
+ top: 20px;
76
+ left: 20px;
70
77
  }
78
+
79
+ @include media-breakpoint-down(xl) {
80
+ .cherita-spatial-controls {
81
+ top: 100px;
82
+ }
83
+ .cherita-toolbox {
84
+ right: 20px;
85
+ left: auto;
86
+ }
87
+ }
88
+
89
+
90
+
91
+
71
92
  .cherita-legend {
72
93
  position: absolute;
73
94
  z-index: 10;
74
95
  bottom: 20px;
75
- left: 20px;
96
+ right: 20px;
76
97
  width: 200px;
77
98
  }
78
99
 
@@ -11,9 +11,10 @@ var _react = _interopRequireWildcard(require("react"));
11
11
  var _DatasetContext = require("../../context/DatasetContext");
12
12
  var _requests = require("../../utils/requests");
13
13
  var _chromaJs = _interopRequireDefault(require("chroma-js"));
14
- var _colorHelper = require("../../helpers/color-helper");
15
14
  var _LoadingSpinner = require("../../utils/LoadingSpinner");
16
15
  var _reactBootstrap = require("react-bootstrap");
16
+ var _reactFontawesome = require("@fortawesome/react-fontawesome");
17
+ var _freeSolidSvgIcons = require("@fortawesome/free-solid-svg-icons");
17
18
  var _jsxRuntime = require("react/jsx-runtime");
18
19
  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); }
19
20
  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 && Object.prototype.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; }
@@ -59,7 +60,6 @@ function ObsColsList() {
59
60
  const [params, setParams] = (0, _react.useState)({
60
61
  url: dataset.url
61
62
  });
62
- const colorHelper = new _colorHelper.ColorHelper();
63
63
  (0, _react.useEffect)(() => {
64
64
  setParams(p => {
65
65
  return {
@@ -133,7 +133,7 @@ function ObsColsList() {
133
133
  value: obs
134
134
  });
135
135
  }, [obs, dispatch]);
136
- function categoricalList(item) {
136
+ const categoricalList = (0, _react.useCallback)(function (item) {
137
137
  let active = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
138
138
  return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactBootstrap.Accordion.Item, {
139
139
  eventKey: item.name,
@@ -141,21 +141,76 @@ function ObsColsList() {
141
141
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Accordion.Header, {
142
142
  children: item.name
143
143
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Accordion.Body, {
144
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.ListGroup, {
145
- variant: "flush",
146
- children: item.values.map((value, index) => /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactBootstrap.ListGroup.Item, {
147
- children: [value, /*#__PURE__*/(0, _jsxRuntime.jsx)("span", {
148
- className: "cm-string cm-color",
149
- style: {
150
- backgroundColor: "rgb(".concat(obs[item.name]["state"][index]["color"], ")")
151
- }
152
- })]
153
- }, index))
144
+ children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactBootstrap.ListGroup, {
145
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.ListGroup.Item, {
146
+ children: /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
147
+ class: "d-flex",
148
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
149
+ class: "flex-grow-1",
150
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Form.Check, {
151
+ // prettier-ignore
152
+ type: "switch",
153
+ id: "custom-switch",
154
+ label: "Toggle all"
155
+ })
156
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
157
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.ButtonGroup, {
158
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Button, {
159
+ variant: "secondary",
160
+ size: "sm",
161
+ onClick: key => {
162
+ if (key != null) {
163
+ dispatch({
164
+ type: "obsSelected",
165
+ obs: obsColsList.find(obs => obs.name === item.name)
166
+ });
167
+ dispatch({
168
+ type: "set.colorEncoding",
169
+ value: "obs"
170
+ });
171
+ }
172
+ },
173
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactFontawesome.FontAwesomeIcon, {
174
+ icon: _freeSolidSvgIcons.faDroplet
175
+ })
176
+ })
177
+ })
178
+ })]
179
+ })
180
+ }), item.values.map((value, index) => /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.ListGroup.Item, {
181
+ children: /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
182
+ class: "d-flex",
183
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
184
+ class: "flex-grow-1",
185
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Form.Check, {
186
+ // prettier-ignore
187
+ type: "switch",
188
+ id: "custom-switch",
189
+ label: value
190
+ })
191
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
192
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)("svg", {
193
+ xmlns: "http://www.w3.org/2000/svg",
194
+ width: "24",
195
+ height: "24",
196
+ fill: "currentColor",
197
+ viewBox: "0 0 10 10",
198
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)("rect", {
199
+ x: "0",
200
+ y: "0",
201
+ width: "10",
202
+ height: "10",
203
+ fill: "rgb(".concat(obs[item.name]["state"][index]["color"], ")")
204
+ })
205
+ })
206
+ })]
207
+ })
208
+ }, value))]
154
209
  })
155
210
  })]
156
211
  }, item.name);
157
- }
158
- function continuousList(item) {
212
+ }, [obs]);
213
+ const continuousList = (0, _react.useCallback)(function (item) {
159
214
  let active = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
160
215
  return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactBootstrap.Accordion.Item, {
161
216
  eventKey: item.name,
@@ -176,8 +231,8 @@ function ObsColsList() {
176
231
  })]
177
232
  })]
178
233
  }, item.name);
179
- }
180
- function otherList(item) {
234
+ }, []);
235
+ const otherList = (0, _react.useCallback)(function (item) {
181
236
  let active = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
182
237
  return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactBootstrap.Accordion.Item, {
183
238
  eventKey: item.name,
@@ -188,7 +243,7 @@ function ObsColsList() {
188
243
  children: item.type
189
244
  })]
190
245
  }, item.name);
191
- }
246
+ }, []);
192
247
  const obsList = (0, _react.useMemo)(() => obsColsList.map(item => {
193
248
  if (item.type === "categorical") {
194
249
  return categoricalList(item, active);
@@ -197,7 +252,7 @@ function ObsColsList() {
197
252
  } else {
198
253
  return otherList(item, active);
199
254
  }
200
- }), [obsColsList, active]);
255
+ }), [obsColsList, categoricalList, active, continuousList, otherList]);
201
256
  if (!serverError) {
202
257
  return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
203
258
  className: "position-relative",
@@ -206,14 +261,7 @@ function ObsColsList() {
206
261
  children: [isPending && /*#__PURE__*/(0, _jsxRuntime.jsx)(_LoadingSpinner.LoadingSpinner, {}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Accordion, {
207
262
  flush: true,
208
263
  defaultActiveKey: active,
209
- onSelect: key => {
210
- if (key != null) {
211
- dispatch({
212
- type: "obsSelected",
213
- obs: obsColsList.find(obs => obs.name === key)
214
- });
215
- }
216
- },
264
+ alwaysOpen: true,
217
265
  children: obsList
218
266
  })]
219
267
  })
@@ -10,7 +10,14 @@ var _requests = require("../../utils/requests");
10
10
  var _DatasetContext = require("../../context/DatasetContext");
11
11
  var _LoadingSpinner = require("../../utils/LoadingSpinner");
12
12
  var _reactBootstrap = require("react-bootstrap");
13
+ var _Dropdown = _interopRequireDefault(require("react-bootstrap/Dropdown"));
14
+ var _Button = _interopRequireDefault(require("react-bootstrap/Button"));
15
+ var _DropdownButton = _interopRequireDefault(require("react-bootstrap/DropdownButton"));
16
+ var _ButtonGroup = _interopRequireDefault(require("react-bootstrap/ButtonGroup"));
17
+ var _OverlayTrigger = _interopRequireDefault(require("react-bootstrap/OverlayTrigger"));
18
+ var _Tooltip = _interopRequireDefault(require("react-bootstrap/Tooltip"));
13
19
  var _jsxRuntime = require("react/jsx-runtime");
20
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
14
21
  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); }
15
22
  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 && Object.prototype.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; }
16
23
  function ObsmKeysList() {
@@ -48,9 +55,8 @@ function ObsmKeysList() {
48
55
  }
49
56
  }, [dataset.selectedObsm]);
50
57
  const obsmList = obsmKeysList.map(item => {
51
- return /*#__PURE__*/(0, _jsxRuntime.jsx)("button", {
52
- type: "button",
53
- className: "list-group-item list-grou-item-action ".concat(active === item && "active"),
58
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_Dropdown.default.Item, {
59
+ className: "custom ".concat(active === item && "active"),
54
60
  onClick: () => {
55
61
  dispatch({
56
62
  type: "obsmSelected",
@@ -61,18 +67,28 @@ function ObsmKeysList() {
61
67
  }, item);
62
68
  });
63
69
  if (!serverError) {
64
- return /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
65
- className: "",
66
- children: [isPending && /*#__PURE__*/(0, _jsxRuntime.jsx)(_LoadingSpinner.LoadingSpinner, {}), /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
67
- className: "list-group overflow-auto mh-100",
70
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
71
+ children: [isPending && /*#__PURE__*/(0, _jsxRuntime.jsx)(_LoadingSpinner.LoadingSpinner, {}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_DropdownButton.default, {
72
+ as: _ButtonGroup.default,
73
+ title: dataset.selectedObsm,
74
+ id: "bg-nested-dropdown",
75
+ size: "sm",
68
76
  children: obsmList
69
77
  })]
70
78
  });
71
79
  } else {
72
- return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
73
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Alert, {
74
- variant: "danger",
80
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_OverlayTrigger.default, {
81
+ placement: "top",
82
+ delay: {
83
+ show: 100,
84
+ hide: 200
85
+ },
86
+ overlay: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Tooltip.default, {
75
87
  children: serverError.message
88
+ }),
89
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Button.default, {
90
+ variant: "danger",
91
+ children: "Error"
76
92
  })
77
93
  });
78
94
  }
@@ -4,63 +4,73 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.Legend = Legend;
7
- require("bootstrap/dist/css/bootstrap.min.css");
8
- var _Dropdown = _interopRequireDefault(require("react-bootstrap/Dropdown"));
9
7
  var _react = require("react");
10
- var _DatasetContext = require("../../context/DatasetContext");
8
+ require("bootstrap/dist/css/bootstrap.min.css");
11
9
  var _lodash = _interopRequireDefault(require("lodash"));
12
- var _colorHelper = require("../../helpers/color-helper");
13
- var _OverlayTrigger = _interopRequireDefault(require("react-bootstrap/OverlayTrigger"));
14
- var _layers = require("@nebula.gl/layers");
15
- var _chromaJs = _interopRequireDefault(require("chroma-js"));
16
- var _Tooltip = _interopRequireDefault(require("react-bootstrap/Tooltip"));
17
- var _constants = require("../../constants/constants");
18
- var _editModes = require("@nebula.gl/edit-modes");
19
- var _Button = _interopRequireDefault(require("react-bootstrap/Button"));
20
- var _DropdownButton = _interopRequireDefault(require("react-bootstrap/DropdownButton"));
21
- var _ButtonGroup = _interopRequireDefault(require("react-bootstrap/ButtonGroup"));
22
- var _reactFontawesome = require("@fortawesome/react-fontawesome");
23
- var _freeSolidSvgIcons = require("@fortawesome/free-solid-svg-icons");
10
+ var _DatasetContext = require("../../context/DatasetContext");
24
11
  var _jsxRuntime = require("react/jsx-runtime");
25
12
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
26
13
  function Legend(_ref) {
27
14
  let {
28
- values
15
+ scale
29
16
  } = _ref;
30
17
  const dataset = (0, _DatasetContext.useDataset)();
31
- const colorHelper = new _colorHelper.ColorHelper();
32
- if (dataset.colorEncoding === "var") {
33
- let c = colorHelper.getScale(dataset, values);
34
- var dom = c.domain ? c.domain() : [0, 1],
35
- dmin = Math.min(dom[0], dom[dom.length - 1]),
36
- dmax = Math.max(dom[dom.length - 1], dom[0]);
37
- let legendList = [];
38
- for (var i = 0; i <= 100; i++) {
39
- var color = c(dmin + i / 100 * (dmax - dmin));
40
- //console.log(color.hex());
41
- legendList.push( /*#__PURE__*/(0, _jsxRuntime.jsx)("span", {
42
- className: "grad-step",
43
- style: {
44
- backgroundColor: color.hex()
45
- }
46
- }, i));
18
+ const [legendData, setLegendData] = (0, _react.useState)({
19
+ dmin: 0,
20
+ dmax: 1,
21
+ list: []
22
+ });
23
+ (0, _react.useEffect)(() => {
24
+ if (scale) {
25
+ const dom = scale.domain ? scale.domain() : [0, 1];
26
+ const dmin = Math.min(dom[0], dom[dom.length - 1]);
27
+ const dmax = Math.max(dom[dom.length - 1], dom[0]);
28
+ const spanList = _lodash.default.range(100).map(i => {
29
+ var color = scale(dmin + i / 100 * (dmax - dmin)).hex();
30
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)("span", {
31
+ className: "grad-step",
32
+ style: {
33
+ backgroundColor: color
34
+ }
35
+ }, i);
36
+ });
37
+ setLegendData({
38
+ dmin: dmin,
39
+ dmax: dmax,
40
+ list: spanList
41
+ });
47
42
  }
43
+ }, [scale]);
44
+ if (dataset.colorEncoding === "var" && scale) {
48
45
  return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
49
46
  className: "cherita-legend",
50
47
  children: /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
51
48
  className: "gradient",
52
- children: [legendList, /*#__PURE__*/(0, _jsxRuntime.jsx)("span", {
49
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("p", {
50
+ className: "small m-0 p-0",
51
+ children: dataset.selectedVar ? dataset.selectedVar.name : ""
52
+ }), legendData.list, /*#__PURE__*/(0, _jsxRuntime.jsx)("span", {
53
53
  className: "domain-min",
54
- children: dmin.toString()
54
+ children: legendData.dmin.toFixed(1)
55
55
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)("span", {
56
56
  className: "domain-med",
57
- children: ((dmin + dmax) * 0.5).toString()
57
+ children: ((legendData.dmin + legendData.dmax) * 0.5).toFixed(1)
58
58
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)("span", {
59
59
  className: "domain-max",
60
- children: dmax.toString()
60
+ children: legendData.dmax.toFixed(1)
61
61
  })]
62
62
  })
63
63
  });
64
+ } else {
65
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
66
+ className: "cherita-legend",
67
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
68
+ className: "gradient",
69
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)("p", {
70
+ className: "small m-0 p-0",
71
+ children: dataset.selectedObs ? dataset.selectedObs.name : ""
72
+ })
73
+ })
74
+ });
64
75
  }
65
- return /*#__PURE__*/(0, _jsxRuntime.jsx)(_jsxRuntime.Fragment, {});
66
76
  }
@@ -5,20 +5,23 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.Scatterplot = Scatterplot;
7
7
  exports.ScatterplotControls = ScatterplotControls;
8
- require("bootstrap/dist/css/bootstrap.min.css");
9
8
  var _react = _interopRequireWildcard(require("react"));
9
+ var _lodash = _interopRequireDefault(require("lodash"));
10
+ require("bootstrap/dist/css/bootstrap.min.css");
10
11
  var _react2 = _interopRequireDefault(require("@deck.gl/react"));
11
12
  var _layers = require("@deck.gl/layers");
12
13
  var _layers2 = require("@nebula.gl/layers");
13
14
  var _editModes = require("@nebula.gl/edit-modes");
14
15
  var _Dropdown = _interopRequireDefault(require("react-bootstrap/Dropdown"));
15
16
  var _Toolbox = require("./Toolbox");
17
+ var _SpatialControls = require("./SpatialControls");
16
18
  var _Legend = require("./Legend");
17
19
  var _constants = require("../../constants/constants");
18
20
  var _DatasetContext = require("../../context/DatasetContext");
19
21
  var _mapHelper = require("../../helpers/map-helper");
20
22
  var _zarrHelper = require("../../helpers/zarr-helper");
21
23
  var _colorHelper = require("../../helpers/color-helper");
24
+ var _LoadingSpinner = require("../../utils/LoadingSpinner");
22
25
  var _jsxRuntime = require("react/jsx-runtime");
23
26
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
24
27
  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); }
@@ -47,138 +50,232 @@ function ScatterplotControls() {
47
50
  })]
48
51
  });
49
52
  }
53
+ const INITIAL_VIEW_STATE = {
54
+ longitude: 0,
55
+ latitude: 0,
56
+ zoom: 0,
57
+ maxZoom: 16,
58
+ pitch: 0,
59
+ bearing: 0
60
+ };
61
+ const DEFAULT_DATA_POINT = {
62
+ value: null,
63
+ position: null,
64
+ color: null
65
+ };
50
66
  function Scatterplot(_ref) {
67
+ var _dataset$selectedObs;
51
68
  let {
52
69
  radius = 30
53
70
  } = _ref;
54
71
  const dataset = (0, _DatasetContext.useDataset)();
55
- const dispatch = (0, _DatasetContext.useDatasetDispatch)();
72
+ const {
73
+ getScale,
74
+ getColor
75
+ } = (0, _colorHelper.useColor)();
76
+ const [viewState, setViewState] = (0, _react.useState)(INITIAL_VIEW_STATE);
56
77
  const [features, setFeatures] = (0, _react.useState)({
57
78
  type: "FeatureCollection",
58
79
  features: []
59
80
  });
60
81
  const [mode, setMode] = (0, _react.useState)(() => _editModes.ViewMode);
61
82
  const [selectedFeatureIndexes, setSelectedFeatureIndexes] = (0, _react.useState)([]);
62
- let [featureState, setFeatureState] = (0, _react.useState)([]);
63
- let [data, setData] = (0, _react.useState)([]);
64
- let [position, setPosition] = (0, _react.useState)([]);
65
- let [values, setValues] = (0, _react.useState)([]);
66
- let [viewport, setViewport] = (0, _react.useState)({
67
- longitude: 0,
68
- latitude: 0,
69
- zoom: 0,
70
- maxZoom: 16,
71
- pitch: 0,
72
- bearing: 0
83
+ const [featureState, setFeatureState] = (0, _react.useState)([]);
84
+ const [scale, setScale] = (0, _react.useState)(() => getScale());
85
+ const [data, setData] = (0, _react.useState)([]);
86
+ const [obsmParams, setObsmParams] = (0, _react.useState)({
87
+ url: dataset.url,
88
+ path: "obsm/" + dataset.selectedObsm
73
89
  });
90
+ const [xParams, setXParams] = (0, _react.useState)({
91
+ url: dataset.url,
92
+ path: "X"
93
+ });
94
+ const [obsParams, setObsParams] = (0, _react.useState)({
95
+ url: dataset.url,
96
+ path: "obs/" + ((_dataset$selectedObs = dataset.selectedObs) === null || _dataset$selectedObs === void 0 ? void 0 : _dataset$selectedObs.name) + "/codes"
97
+ });
98
+
99
+ // needs to be wrapped in useMemo as it is an array an could cause an infinite loop otherwise
100
+ const xSelection = (0, _react.useMemo)(() => {
101
+ var _dataset$selectedVar;
102
+ return [null, (_dataset$selectedVar = dataset.selectedVar) === null || _dataset$selectedVar === void 0 ? void 0 : _dataset$selectedVar.matrix_index];
103
+ }, [dataset.selectedVar]);
104
+ const obsmData = (0, _zarrHelper.useZarr)(obsmParams, null, _zarrHelper.GET_OPTIONS);
105
+ const xData = (0, _zarrHelper.useZarr)(xParams, xSelection, _zarrHelper.GET_OPTIONS);
106
+ const obsData = (0, _zarrHelper.useZarr)(obsParams, null, _zarrHelper.GET_OPTIONS);
107
+ (0, _react.useEffect)(() => {
108
+ setObsmParams(p => {
109
+ return {
110
+ ...p,
111
+ path: "obsm/" + dataset.selectedObsm
112
+ };
113
+ });
114
+ }, [dataset.selectedObsm]);
115
+ (0, _react.useEffect)(() => {
116
+ setXParams(p => {
117
+ var _dataset$selectedVar2;
118
+ return {
119
+ ...p,
120
+ s: [null, (_dataset$selectedVar2 = dataset.selectedVar) === null || _dataset$selectedVar2 === void 0 ? void 0 : _dataset$selectedVar2.matrix_index]
121
+ };
122
+ });
123
+ }, [dataset.selectedVar]);
124
+ (0, _react.useEffect)(() => {
125
+ setObsParams(p => {
126
+ var _dataset$selectedObs2;
127
+ return {
128
+ ...p,
129
+ path: "obs/" + ((_dataset$selectedObs2 = dataset.selectedObs) === null || _dataset$selectedObs2 === void 0 ? void 0 : _dataset$selectedObs2.name) + "/codes"
130
+ };
131
+ });
132
+ }, [dataset.selectedObs]);
133
+ (0, _react.useEffect)(() => {
134
+ setObsmParams(p => {
135
+ return {
136
+ ...p,
137
+ url: dataset.url
138
+ };
139
+ });
140
+ setXParams(p => {
141
+ return {
142
+ ...p,
143
+ url: dataset.url
144
+ };
145
+ });
146
+ setObsParams(p => {
147
+ return {
148
+ ...p,
149
+ url: dataset.url
150
+ };
151
+ });
152
+ }, [dataset.url]);
153
+
154
+ // @TODO: assert length of obsmData, xData, obsData is equal
155
+
74
156
  (0, _react.useEffect)(() => {
75
- setData(function (prevState, props) {
76
- const colorHelper = new _colorHelper.ColorHelper();
77
- let scale = dataset.colorEncoding === "var" ? colorHelper.getScale(dataset.controls.colorScale, values) : null;
78
- var data = position.map(function (e, i) {
79
- var _dataset$obs$dataset$, _dataset$selectedObs;
157
+ if (!obsmData.isPending && !obsmData.serverError) {
158
+ setData(d => {
159
+ return _lodash.default.map(obsmData.data, (p, index) => {
160
+ return _lodash.default.defaults({
161
+ position: p
162
+ }, d === null || d === void 0 ? void 0 : d[index], DEFAULT_DATA_POINT);
163
+ });
164
+ });
165
+ const mapHelper = new _mapHelper.MapHelper();
166
+ const {
167
+ latitude,
168
+ longitude,
169
+ zoom
170
+ } = mapHelper.fitBounds(obsmData.data);
171
+ setViewState(v => {
80
172
  return {
81
- index: i,
82
- position: [position[i][0], position[i][1]],
83
- value: values[i],
84
- color: colorHelper.getColor(dataset.colorEncoding, (_dataset$obs$dataset$ = dataset.obs[(_dataset$selectedObs = dataset.selectedObs) === null || _dataset$selectedObs === void 0 ? void 0 : _dataset$selectedObs.name]) === null || _dataset$obs$dataset$ === void 0 ? void 0 : _dataset$obs$dataset$.state, values[i], scale)
173
+ ...v,
174
+ longitude: longitude,
175
+ latitude: latitude,
176
+ zoom: zoom
85
177
  };
86
178
  });
87
- return data;
88
- });
89
- }, [position, values, dataset.controls.colorScale, dataset.colorEncoding, dataset.obs, dataset.selectedObs]);
90
- (0, _react.useEffect)(() => {
91
- if (dataset.selectedObsm) {
92
- const helper = new _mapHelper.MapHelper();
93
- const zarrHelper = new _zarrHelper.ZarrHelper();
94
- const fetchObsm = async () => {
95
- const z = await zarrHelper.open(dataset.url, "obsm/" + dataset.selectedObsm);
96
- await z.get(null, _zarrHelper.GET_OPTIONS).then(result => {
97
- const {
98
- latitude,
99
- longitude,
100
- zoom
101
- } = helper.fitBounds(result.data);
102
- setViewport({
103
- longitude: latitude,
104
- latitude: longitude,
105
- zoom: zoom,
106
- maxZoom: 16,
107
- pitch: 0,
108
- bearing: 0
109
- });
110
- setPosition(result.data);
179
+ } else if (!obsmData.isPending && obsmData.serverError) {
180
+ setData(d => {
181
+ return _lodash.default.map(d, e => {
182
+ return _lodash.default.defaults({
183
+ position: null
184
+ }, e, DEFAULT_DATA_POINT);
111
185
  });
112
- };
113
- fetchObsm().catch(console.error);
186
+ });
114
187
  }
115
- }, [dataset.url, dataset.selectedObsm]);
188
+ }, [dataset.selectedObsm, obsmData.data, obsmData.isPending, obsmData.serverError]);
116
189
  (0, _react.useEffect)(() => {
117
- if (dataset.selectedVar) {
118
- const zarrHelper = new _zarrHelper.ZarrHelper();
119
- const fetchData = async () => {
120
- const z = await zarrHelper.open(dataset.url, "X");
121
- await z.get([null, dataset.selectedVar.matrix_index], _zarrHelper.GET_OPTIONS).then(result => {
122
- setValues(result.data);
123
- dispatch({
124
- type: "set.colorEncoding",
125
- value: "var"
190
+ if (dataset.colorEncoding === "var") {
191
+ if (!xData.isPending && !xData.serverError) {
192
+ const s = getScale(xData.data);
193
+ setScale(() => s);
194
+ setData(d => {
195
+ return _lodash.default.map(xData.data, (v, index) => {
196
+ return _lodash.default.defaults({
197
+ value: v,
198
+ color: getColor(s, v)
199
+ }, d === null || d === void 0 ? void 0 : d[index], DEFAULT_DATA_POINT);
126
200
  });
127
201
  });
128
- };
129
- fetchData().catch(console.error);
202
+ } else if (!xData.isPending && xData.serverError) {
203
+ const s = getScale();
204
+ setScale(() => s);
205
+ setData(d => {
206
+ return _lodash.default.map(d, e => {
207
+ return _lodash.default.defaults({
208
+ value: null,
209
+ color: null
210
+ }, e, DEFAULT_DATA_POINT);
211
+ });
212
+ });
213
+ }
130
214
  }
131
- }, [dataset.url, dataset.selectedVar, dispatch]);
215
+ }, [dataset.colorEncoding, xData.data, xData.isPending, xData.serverError, getScale, getColor]);
132
216
  (0, _react.useEffect)(() => {
133
- if (dataset.selectedObs) {
134
- const zarrHelper = new _zarrHelper.ZarrHelper();
135
- const fetchData = async () => {
136
- const z = await zarrHelper.open(dataset.url, "obs/" + dataset.selectedObs.name + "/codes");
137
- await z.get().then(result => {
138
- setValues(result.data);
139
- dispatch({
140
- type: "set.colorEncoding",
141
- value: "obs"
217
+ if (dataset.colorEncoding === "obs") {
218
+ if (!obsData.isPending && !obsData.serverError) {
219
+ const s = getScale(obsData.data);
220
+ setScale(() => s);
221
+ setData(d => {
222
+ return _lodash.default.map(obsData.data, (v, index) => {
223
+ return _lodash.default.defaults({
224
+ value: v,
225
+ color: getColor(s, v)
226
+ }, d === null || d === void 0 ? void 0 : d[index], DEFAULT_DATA_POINT);
227
+ });
228
+ });
229
+ } else if (!obsData.isPending && obsData.serverError) {
230
+ const s = getScale();
231
+ setScale(() => s);
232
+ setData(d => {
233
+ return _lodash.default.map(d, e => {
234
+ return _lodash.default.defaults({
235
+ value: null,
236
+ color: null
237
+ }, e, DEFAULT_DATA_POINT);
142
238
  });
143
239
  });
144
- };
145
- fetchData().catch(console.error);
146
- }
147
- }, [dataset.url, dataset.selectedObs, dispatch]);
148
- const layers = [new _layers.ScatterplotLayer({
149
- id: "cherita-layer-scatterplot",
150
- data,
151
- radiusScale: radius,
152
- radiusMinPixels: 1,
153
- getPosition: d => d.position,
154
- getFillColor: d => d.color,
155
- getRadius: 1
156
- }), new _layers2.EditableGeoJsonLayer({
157
- id: "cherita-layer-draw",
158
- data: features,
159
- mode,
160
- selectedFeatureIndexes,
161
- onEdit: _ref2 => {
162
- let {
163
- updatedData,
164
- editType,
165
- editContext
166
- } = _ref2;
167
- setFeatures(updatedData);
168
- let updatedSelectedFeatureIndexes = selectedFeatureIndexes;
169
- setFeatureState({
170
- data: updatedData
171
- });
172
- if (editType === "addFeature") {
173
- // when a drawing is complete, the value of editType becomes addFeature
174
- const {
175
- featureIndexes
176
- } = editContext; //extracting indexes of current features selected
177
- updatedSelectedFeatureIndexes = [...selectedFeatureIndexes, ...featureIndexes];
178
240
  }
179
- setSelectedFeatureIndexes(updatedSelectedFeatureIndexes); //now update your state
180
241
  }
181
- })];
242
+ }, [dataset.colorEncoding, obsData.data, obsData.isPending, obsData.serverError, getScale, getColor]);
243
+ const layers = (0, _react.useMemo)(() => {
244
+ return [new _layers.ScatterplotLayer({
245
+ id: "cherita-layer-scatterplot",
246
+ data: data,
247
+ radiusScale: radius,
248
+ radiusMinPixels: 1,
249
+ getPosition: d => d.position,
250
+ getFillColor: d => d.color,
251
+ getRadius: 1
252
+ }), new _layers2.EditableGeoJsonLayer({
253
+ id: "cherita-layer-draw",
254
+ data: features,
255
+ mode: mode,
256
+ selectedFeatureIndexes,
257
+ onEdit: _ref2 => {
258
+ let {
259
+ updatedData,
260
+ editType,
261
+ editContext
262
+ } = _ref2;
263
+ setFeatures(updatedData);
264
+ let updatedSelectedFeatureIndexes = selectedFeatureIndexes;
265
+ setFeatureState({
266
+ data: updatedData
267
+ });
268
+ if (editType === "addFeature") {
269
+ // when a drawing is complete, the value of editType becomes addFeature
270
+ const {
271
+ featureIndexes
272
+ } = editContext; //extracting indexes of current features selected
273
+ updatedSelectedFeatureIndexes = [...selectedFeatureIndexes, ...featureIndexes];
274
+ }
275
+ setSelectedFeatureIndexes(updatedSelectedFeatureIndexes); //now update your state
276
+ }
277
+ })];
278
+ }, [data, features, mode, radius, selectedFeatureIndexes]);
182
279
  function onLayerClick(info) {
183
280
  if (mode !== _editModes.ViewMode) {
184
281
  // don't change selection while editing
@@ -186,22 +283,28 @@ function Scatterplot(_ref) {
186
283
  }
187
284
  setSelectedFeatureIndexes(info.object ? [info.index] : []);
188
285
  }
189
- return /*#__PURE__*/(0, _jsxRuntime.jsx)(_jsxRuntime.Fragment, {
190
- children: /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
191
- className: "cherita-scatterplot",
192
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_react2.default, {
193
- layers: layers,
194
- initialViewState: viewport,
195
- controller: true,
196
- onClick: onLayerClick
197
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_Toolbox.Toolbox, {
198
- mode: mode,
199
- setMode: setMode,
200
- features: mode,
201
- setFeatures: setFeatures
202
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_Legend.Legend, {
203
- values: values
204
- })]
205
- })
286
+
287
+ // @TODO: add error message
288
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
289
+ className: "cherita-scatterplot",
290
+ children: [(obsmData.isPending || xData.isPending || obsmData.isPending) && /*#__PURE__*/(0, _jsxRuntime.jsx)(_LoadingSpinner.LoadingSpinner, {}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_react2.default, {
291
+ viewState: viewState,
292
+ onViewStateChange: e => setViewState(e.viewState),
293
+ controller: true,
294
+ layers: layers,
295
+ onClick: onLayerClick
296
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_SpatialControls.SpatialControls, {
297
+ mode: mode,
298
+ setMode: setMode,
299
+ features: mode,
300
+ setFeatures: setFeatures
301
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_Toolbox.Toolbox, {
302
+ mode: mode,
303
+ setMode: setMode,
304
+ features: mode,
305
+ setFeatures: setFeatures
306
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_Legend.Legend, {
307
+ scale: scale
308
+ })]
206
309
  });
207
310
  }
@@ -0,0 +1,121 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.SpatialControls = SpatialControls;
7
+ require("bootstrap/dist/css/bootstrap.min.css");
8
+ var _Dropdown = _interopRequireDefault(require("react-bootstrap/Dropdown"));
9
+ var _react = require("react");
10
+ var _editModes = require("@nebula.gl/edit-modes");
11
+ var _Button = _interopRequireDefault(require("react-bootstrap/Button"));
12
+ var _DropdownButton = _interopRequireDefault(require("react-bootstrap/DropdownButton"));
13
+ var _ButtonGroup = _interopRequireDefault(require("react-bootstrap/ButtonGroup"));
14
+ var _reactFontawesome = require("@fortawesome/react-fontawesome");
15
+ var _freeSolidSvgIcons = require("@fortawesome/free-solid-svg-icons");
16
+ var _cheritaReact = require("@haniffalab/cherita-react");
17
+ var _jsxRuntime = require("react/jsx-runtime");
18
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
19
+ function SpatialControls(_ref) {
20
+ let {
21
+ mode,
22
+ setMode,
23
+ features,
24
+ setFeatures
25
+ } = _ref;
26
+ const [showControls, setShowControls] = (0, _react.useState)(false);
27
+ const handleCloseControls = () => setShowControls(false);
28
+ const handleShowControls = () => setShowControls(true);
29
+ const onSelect = (eventKey, event) => {
30
+ console.log(eventKey); // selected event will trigger
31
+ switch (eventKey) {
32
+ case "DrawPolygonMode":
33
+ setMode(() => _editModes.DrawPolygonMode);
34
+ break;
35
+ case "DrawLineStringMode":
36
+ setMode(() => _editModes.DrawLineStringMode);
37
+ break;
38
+ case "DrawPolygonByDraggingMode":
39
+ setMode(() => _editModes.DrawPolygonByDraggingMode);
40
+ break;
41
+ case "DrawRectangleMode":
42
+ setMode(() => _editModes.DrawRectangleMode);
43
+ break;
44
+ case "ModifyMode":
45
+ setMode(() => _editModes.ModifyMode);
46
+ break;
47
+ default:
48
+ setMode(() => _editModes.ViewMode);
49
+ }
50
+ };
51
+ const deleteFeatures = (eventKey, event) => {
52
+ console.log(eventKey); // selected event will trigger
53
+ setFeatures({
54
+ type: "FeatureCollection",
55
+ features: []
56
+ });
57
+ };
58
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
59
+ className: "cherita-spatial-controls",
60
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_ButtonGroup.default, {
61
+ vertical: true,
62
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_Button.default, {
63
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactFontawesome.FontAwesomeIcon, {
64
+ icon: _freeSolidSvgIcons.faPlus
65
+ })
66
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_Button.default, {
67
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactFontawesome.FontAwesomeIcon, {
68
+ icon: _freeSolidSvgIcons.faMinus
69
+ })
70
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_Button.default, {
71
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactFontawesome.FontAwesomeIcon, {
72
+ icon: _freeSolidSvgIcons.faCrosshairs
73
+ })
74
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_Button.default, {
75
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactFontawesome.FontAwesomeIcon, {
76
+ icon: _freeSolidSvgIcons.faHand
77
+ })
78
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_DropdownButton.default, {
79
+ as: _ButtonGroup.default,
80
+ title: /*#__PURE__*/(0, _jsxRuntime.jsx)(_jsxRuntime.Fragment, {
81
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactFontawesome.FontAwesomeIcon, {
82
+ icon: _freeSolidSvgIcons.faDrawPolygon
83
+ })
84
+ }),
85
+ drop: "end",
86
+ id: "bg-vertical-dropdown-1",
87
+ className: "caret-off",
88
+ onSelect: onSelect,
89
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_Dropdown.default.Header, {
90
+ children: "Selection tools"
91
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_Dropdown.default.Divider, {}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_Dropdown.default.Item, {
92
+ eventKey: "DrawPolygonMode",
93
+ children: "Draw a polygon"
94
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_Dropdown.default.Item, {
95
+ eventKey: "DrawPolygonByDraggingMode",
96
+ children: "Draw a Polygon by Dragging"
97
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_Dropdown.default.Item, {
98
+ eventKey: "ModifyMode",
99
+ children: "Modify polygons"
100
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_Dropdown.default.Item, {
101
+ eventKey: "ViewMode",
102
+ children: "ViewMode"
103
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_Dropdown.default.Item, {
104
+ onClick: deleteFeatures,
105
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactFontawesome.FontAwesomeIcon, {
106
+ icon: _freeSolidSvgIcons.faTrash
107
+ }), " Delete Plydons"]
108
+ })]
109
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_Button.default, {
110
+ onClick: handleShowControls,
111
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactFontawesome.FontAwesomeIcon, {
112
+ icon: _freeSolidSvgIcons.faSliders
113
+ })
114
+ })]
115
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_cheritaReact.OffcanvasControls, {
116
+ show: showControls,
117
+ handleClose: handleCloseControls,
118
+ Controls: _cheritaReact.ScatterplotControls
119
+ })]
120
+ });
121
+ }
@@ -7,7 +7,9 @@ exports.Toolbox = Toolbox;
7
7
  require("bootstrap/dist/css/bootstrap.min.css");
8
8
  var _Dropdown = _interopRequireDefault(require("react-bootstrap/Dropdown"));
9
9
  var _react = require("react");
10
+ var _DatasetContext = require("../../context/DatasetContext");
10
11
  var _editModes = require("@nebula.gl/edit-modes");
12
+ var _cheritaReact = require("@haniffalab/cherita-react");
11
13
  var _Button = _interopRequireDefault(require("react-bootstrap/Button"));
12
14
  var _DropdownButton = _interopRequireDefault(require("react-bootstrap/DropdownButton"));
13
15
  var _ButtonGroup = _interopRequireDefault(require("react-bootstrap/ButtonGroup"));
@@ -22,70 +24,18 @@ function Toolbox(_ref) {
22
24
  features,
23
25
  setFeatures
24
26
  } = _ref;
25
- const onSelect = (eventKey, event) => {
26
- console.log(eventKey); // selected event will trigger
27
- switch (eventKey) {
28
- case "DrawPolygonMode":
29
- setMode(() => _editModes.DrawPolygonMode);
30
- break;
31
- case "DrawLineStringMode":
32
- setMode(() => _editModes.DrawLineStringMode);
33
- break;
34
- case "DrawPolygonByDraggingMode":
35
- setMode(() => _editModes.DrawPolygonByDraggingMode);
36
- break;
37
- case "DrawRectangleMode":
38
- setMode(() => _editModes.DrawRectangleMode);
39
- break;
40
- case "ModifyMode":
41
- setMode(() => _editModes.ModifyMode);
42
- break;
43
- default:
44
- setMode(() => _editModes.ViewMode);
45
- }
46
- };
47
- const deleteFeatures = (eventKey, event) => {
48
- console.log(eventKey); // selected event will trigger
49
- setFeatures({
50
- type: "FeatureCollection",
51
- features: []
52
- });
53
- };
27
+ const dataset = (0, _DatasetContext.useDataset)();
54
28
  return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
55
29
  className: "cherita-toolbox",
56
30
  children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_ButtonGroup.default, {
57
- children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_DropdownButton.default, {
58
- as: _ButtonGroup.default,
59
- title: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
60
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactFontawesome.FontAwesomeIcon, {
61
- icon: _freeSolidSvgIcons.faArrowPointer
62
- }), " Mode"]
63
- }),
64
- id: "bg-nested-dropdown",
65
- onSelect: onSelect,
66
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_Dropdown.default.Item, {
67
- eventKey: "DrawPolygonMode",
68
- children: "DrawPolygonMode"
69
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_Dropdown.default.Item, {
70
- eventKey: "DrawLineStringMode",
71
- children: "DrawLineStringMode"
72
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_Dropdown.default.Item, {
73
- eventKey: "DrawPolygonByDraggingMode",
74
- children: "DrawPolygonByDraggingMode"
75
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_Dropdown.default.Item, {
76
- eventKey: "DrawRectangleMode",
77
- children: "DrawRectangleMode"
78
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_Dropdown.default.Item, {
79
- eventKey: "ModifyMode",
80
- children: "ModifyMode"
81
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_Dropdown.default.Item, {
82
- eventKey: "ViewMode",
83
- children: "ViewMode"
84
- })]
31
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_cheritaReact.ObsmKeysList, {}), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_Button.default, {
32
+ size: "sm",
33
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactFontawesome.FontAwesomeIcon, {
34
+ icon: _freeSolidSvgIcons.faDroplet
35
+ }), " CD14"]
85
36
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_Button.default, {
86
- variant: "primary",
87
- onClick: deleteFeatures,
88
- children: "Delete"
37
+ size: "sm",
38
+ children: "Cells XXXX"
89
39
  })]
90
40
  })
91
41
  });
@@ -7,9 +7,11 @@ exports.VarNamesList = VarNamesList;
7
7
  require("bootstrap/dist/css/bootstrap.min.css");
8
8
  var _react = _interopRequireWildcard(require("react"));
9
9
  var _lodash = _interopRequireDefault(require("lodash"));
10
+ var _reactBootstrap = require("react-bootstrap");
11
+ var _reactFontawesome = require("@fortawesome/react-fontawesome");
12
+ var _freeSolidSvgIcons = require("@fortawesome/free-solid-svg-icons");
10
13
  var _DatasetContext = require("../../context/DatasetContext");
11
14
  var _constants = require("../../constants/constants");
12
- var _reactBootstrap = require("react-bootstrap");
13
15
  var _jsxRuntime = require("react/jsx-runtime");
14
16
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
15
17
  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); }
@@ -55,6 +57,10 @@ function VarNamesList(_ref) {
55
57
  type: "varSelected",
56
58
  var: item
57
59
  });
60
+ dispatch({
61
+ type: "set.colorEncoding",
62
+ value: "var"
63
+ });
58
64
  } else if (mode === _constants.SELECTION_MODES.MULTIPLE) {
59
65
  dispatch({
60
66
  type: "multiVarSelected",
@@ -65,36 +71,67 @@ function VarNamesList(_ref) {
65
71
  const makeList = (0, _react.useCallback)(vars => {
66
72
  return vars.map(item => {
67
73
  if (item && mode === _constants.SELECTION_MODES.SINGLE) {
68
- return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Button, {
69
- type: "button",
70
- variant: item.matrix_index !== -1 ? "outline-primary" : "outline-secondary",
71
- className: "".concat(active === item.matrix_index && "active", " m-1"),
72
- onClick: () => {
73
- selectVar(item);
74
- },
75
- disabled: item.matrix_index === -1,
76
- title: item.matrix_index === -1 ? "Not present in data" : "",
77
- children: item.name
78
- }, item.matrix_index);
74
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.ListGroup.Item, {
75
+ children: /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
76
+ class: "d-flex gap-1",
77
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
78
+ class: "flex-grow-1",
79
+ children: item.name
80
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
81
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactFontawesome.FontAwesomeIcon, {
82
+ icon: _freeSolidSvgIcons.faCircleInfo
83
+ })
84
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
85
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Button, {
86
+ type: "button",
87
+ className: "m-0 p-0 px-1 btn-link ".concat(active === item.matrix_index && "active"),
88
+ onClick: () => {
89
+ selectVar(item);
90
+ },
91
+ disabled: item.matrix_index === -1,
92
+ title: item.matrix_index === -1 ? "Not present in data" : "",
93
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactFontawesome.FontAwesomeIcon, {
94
+ icon: _freeSolidSvgIcons.faDroplet
95
+ })
96
+ }, item.matrix_index)
97
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
98
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactFontawesome.FontAwesomeIcon, {
99
+ icon: _freeSolidSvgIcons.faTrash
100
+ })
101
+ })]
102
+ })
103
+ }, item);
79
104
  } else if (mode === _constants.SELECTION_MODES.MULTIPLE) {
80
- return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Button, {
81
- type: "button",
82
- variant: item.matrix_index !== -1 ? "outline-primary" : "outline-secondary",
83
- className: "".concat(active.includes(item.matrix_index) && "active", " m-1"),
84
- onClick: () => {
85
- if (active.includes(item.matrix_index)) {
86
- dispatch({
87
- type: "multiVarDeselected",
88
- var: item
89
- });
90
- } else {
91
- selectVar(item);
92
- }
93
- },
94
- disabled: item.matrix_index === -1,
95
- title: item.matrix_index === -1 ? "Not present in data" : "",
96
- children: item.name
97
- }, item.matrix_index);
105
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.ListGroup.Item, {
106
+ children: /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
107
+ class: "d-flex",
108
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
109
+ class: "flex-grow-1",
110
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Button, {
111
+ type: "button",
112
+ variant: item.matrix_index !== -1 ? "outline-primary" : "outline-secondary",
113
+ className: "".concat(active.includes(item.matrix_index) && "active", " m-1"),
114
+ onClick: () => {
115
+ if (active.includes(item.matrix_index)) {
116
+ dispatch({
117
+ type: "multiVarDeselected",
118
+ var: item
119
+ });
120
+ } else {
121
+ selectVar(item);
122
+ }
123
+ },
124
+ disabled: item.matrix_index === -1,
125
+ title: item.matrix_index === -1 ? "Not present in data" : "",
126
+ children: item.name
127
+ }, item.matrix_index)
128
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
129
+ children: [" ", /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactFontawesome.FontAwesomeIcon, {
130
+ icon: _freeSolidSvgIcons.faPlus
131
+ })]
132
+ })]
133
+ })
134
+ }, item);
98
135
  } else {
99
136
  return null;
100
137
  }
@@ -124,7 +161,9 @@ function VarNamesList(_ref) {
124
161
  },
125
162
  children: "clear"
126
163
  })]
127
- }), varList]
164
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.ListGroup, {
165
+ children: varList
166
+ })]
128
167
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
129
168
  children: ((_dataset$selectedDise = dataset.selectedDisease) === null || _dataset$selectedDise === void 0 ? void 0 : _dataset$selectedDise.id) && ((_dataset$selectedDise2 = dataset.selectedDisease) === null || _dataset$selectedDise2 === void 0 || (_dataset$selectedDise2 = _dataset$selectedDise2.genes) === null || _dataset$selectedDise2 === void 0 ? void 0 : _dataset$selectedDise2.length) > 0 && /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
130
169
  children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
@@ -3,27 +3,35 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.ColorHelper = void 0;
6
+ exports.useColor = void 0;
7
7
  var _chromaJs = _interopRequireDefault(require("chroma-js"));
8
8
  var _lodash = _interopRequireDefault(require("lodash"));
9
9
  var _constants = require("../constants/constants");
10
+ var _DatasetContext = require("../context/DatasetContext");
11
+ var _react = require("react");
10
12
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
11
- function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
12
- function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : String(i); }
13
- 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); }
14
- class ColorHelper {
15
- constructor() {
16
- _defineProperty(this, "getScale", (colorScale, values) => {
17
- return _chromaJs.default.scale(_constants.CHROMA_COLORSCALES[colorScale]).domain([_lodash.default.min(values), _lodash.default.max(values)]);
18
- });
19
- _defineProperty(this, "getColor", function (colorEncoding, state, value) {
20
- let scale = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : _chromaJs.default.scale();
21
- if (colorEncoding === "var") {
22
- return scale(value).rgb();
23
- } else if (colorEncoding === "obs") {
24
- return state !== null && state !== void 0 && state.hasOwnProperty(value) ? state[value]["color"] : null;
25
- }
26
- });
27
- }
28
- }
29
- exports.ColorHelper = ColorHelper;
13
+ const useColor = () => {
14
+ var _dataset$selectedObs2;
15
+ const dataset = (0, _DatasetContext.useDataset)();
16
+ const getScale = (0, _react.useCallback)(function () {
17
+ let values = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
18
+ const c = _chromaJs.default.scale(_constants.CHROMA_COLORSCALES[dataset.controls.colorScale]).domain(values ? [_lodash.default.min(values), _lodash.default.max(values)] : [0, 1]);
19
+ return c;
20
+ }, [dataset.controls.colorScale]);
21
+ const getColor = (0, _react.useCallback)(function (scale, value) {
22
+ let colorEncoding = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : dataset.colorEncoding;
23
+ if (colorEncoding === "var") {
24
+ return scale(value).rgb();
25
+ } else if (colorEncoding === "obs") {
26
+ var _dataset$obs$dataset$, _dataset$selectedObs;
27
+ return (_dataset$obs$dataset$ = dataset.obs[(_dataset$selectedObs = dataset.selectedObs) === null || _dataset$selectedObs === void 0 ? void 0 : _dataset$selectedObs.name]) === null || _dataset$obs$dataset$ === void 0 || (_dataset$obs$dataset$ = _dataset$obs$dataset$.state) === null || _dataset$obs$dataset$ === void 0 || (_dataset$obs$dataset$ = _dataset$obs$dataset$[value]) === null || _dataset$obs$dataset$ === void 0 ? void 0 : _dataset$obs$dataset$["color"];
28
+ } else {
29
+ return null;
30
+ }
31
+ }, [dataset.colorEncoding, dataset.obs, (_dataset$selectedObs2 = dataset.selectedObs) === null || _dataset$selectedObs2 === void 0 ? void 0 : _dataset$selectedObs2.name]);
32
+ return {
33
+ getScale,
34
+ getColor
35
+ };
36
+ };
37
+ exports.useColor = useColor;
@@ -3,7 +3,8 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.ZarrHelper = exports.GET_OPTIONS = void 0;
6
+ exports.useZarr = exports.ZarrHelper = exports.GET_OPTIONS = void 0;
7
+ var _react = require("react");
7
8
  var _zarr = require("zarr");
8
9
  const GET_OPTIONS = exports.GET_OPTIONS = {
9
10
  concurrencyLimit: 10,
@@ -26,4 +27,38 @@ class ZarrHelper {
26
27
  return z;
27
28
  }
28
29
  }
29
- exports.ZarrHelper = ZarrHelper;
30
+ exports.ZarrHelper = ZarrHelper;
31
+ const useZarr = function (_ref2) {
32
+ let {
33
+ url,
34
+ path
35
+ } = _ref2;
36
+ let s = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
37
+ let opts = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
38
+ const [data, setData] = (0, _react.useState)(null);
39
+ const [isPending, setIsPending] = (0, _react.useState)(true);
40
+ const [serverError, setServerError] = (0, _react.useState)(null);
41
+ (0, _react.useEffect)(() => {
42
+ const fetchData = async () => {
43
+ try {
44
+ setIsPending(true);
45
+ setServerError(null);
46
+ const zarrHelper = new ZarrHelper();
47
+ const z = await zarrHelper.open(url, path);
48
+ const result = await z.get(s, opts);
49
+ setData(result.data);
50
+ } catch (error) {
51
+ setServerError(error.message);
52
+ } finally {
53
+ setIsPending(false);
54
+ }
55
+ };
56
+ fetchData();
57
+ }, [opts, path, s, url]);
58
+ return {
59
+ data,
60
+ isPending,
61
+ serverError
62
+ };
63
+ };
64
+ exports.useZarr = useZarr;
@@ -45,6 +45,10 @@ const useVarSearch = () => {
45
45
  type: "multiVarSelected",
46
46
  var: item
47
47
  });
48
+ dispatch({
49
+ type: "set.colorEncoding",
50
+ value: "var"
51
+ });
48
52
  };
49
53
  return {
50
54
  params,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@haniffalab/cherita-react",
3
- "version": "0.2.0-dev.2024-05-09.07fb18ed",
3
+ "version": "0.2.0-dev.2024-05-22.5ce64346",
4
4
  "author": "",
5
5
  "license": "",
6
6
  "main": "dist/index.js",
@@ -78,5 +78,5 @@
78
78
  "url": "https://github.com/haniffalab/cherita-react/issues"
79
79
  },
80
80
  "homepage": "https://github.com/haniffalab/cherita-react#readme",
81
- "prereleaseSha": "07fb18ed8d66be9ecd7817e41b76b1b5cdf3ba7b"
81
+ "prereleaseSha": "5ce64346f33423368e217552e04ebebf2022de06"
82
82
  }