@haniffalab/cherita-react 0.2.0-dev.2024-05-09.97c686f2 → 0.2.0-dev.2024-05-21.ca7d726c

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.
@@ -11,6 +11,7 @@ exports.OffcanvasVars = OffcanvasVars;
11
11
  var _react = require("react");
12
12
  var _Offcanvas = _interopRequireDefault(require("react-bootstrap/Offcanvas"));
13
13
  var _cheritaReact = require("@haniffalab/cherita-react");
14
+ var _SearchBar = require("../search-bar/SearchBar");
14
15
  var _jsxRuntime = require("react/jsx-runtime");
15
16
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
16
17
  function OffcanvasObs(_ref) {
@@ -65,10 +66,12 @@ function OffcanvasVars(_ref3) {
65
66
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Offcanvas.default.Title, {
66
67
  children: "Features"
67
68
  })
68
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_Offcanvas.default.Body, {
69
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_cheritaReact.VarNamesList, {
69
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_Offcanvas.default.Body, {
70
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_SearchBar.SearchBar, {
71
+ searchDiseases: true
72
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_cheritaReact.VarNamesList, {
70
73
  mode: mode
71
- })
74
+ })]
72
75
  })]
73
76
  });
74
77
  }
@@ -11,7 +11,6 @@ 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");
17
16
  var _jsxRuntime = require("react/jsx-runtime");
@@ -59,7 +58,6 @@ function ObsColsList() {
59
58
  const [params, setParams] = (0, _react.useState)({
60
59
  url: dataset.url
61
60
  });
62
- const colorHelper = new _colorHelper.ColorHelper();
63
61
  (0, _react.useEffect)(() => {
64
62
  setParams(p => {
65
63
  return {
@@ -133,7 +131,7 @@ function ObsColsList() {
133
131
  value: obs
134
132
  });
135
133
  }, [obs, dispatch]);
136
- function categoricalList(item) {
134
+ const categoricalList = (0, _react.useCallback)(function (item) {
137
135
  let active = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
138
136
  return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactBootstrap.Accordion.Item, {
139
137
  eventKey: item.name,
@@ -143,19 +141,25 @@ function ObsColsList() {
143
141
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Accordion.Body, {
144
142
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.ListGroup, {
145
143
  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
- })]
144
+ children: item.values.map((value, index) => /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.ListGroup.Item, {
145
+ children: /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
146
+ className: "d-flex justify-content-between",
147
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
148
+ className: "text-wrap text-break",
149
+ children: value
150
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)("span", {
151
+ className: "cm-string cm-color",
152
+ style: {
153
+ backgroundColor: "rgb(".concat(obs[item.name]["state"][index]["color"], ")")
154
+ }
155
+ })]
156
+ })
153
157
  }, index))
154
158
  })
155
159
  })]
156
160
  }, item.name);
157
- }
158
- function continuousList(item) {
161
+ }, [obs]);
162
+ const continuousList = (0, _react.useCallback)(function (item) {
159
163
  let active = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
160
164
  return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactBootstrap.Accordion.Item, {
161
165
  eventKey: item.name,
@@ -176,8 +180,8 @@ function ObsColsList() {
176
180
  })]
177
181
  })]
178
182
  }, item.name);
179
- }
180
- function otherList(item) {
183
+ }, []);
184
+ const otherList = (0, _react.useCallback)(function (item) {
181
185
  let active = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
182
186
  return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactBootstrap.Accordion.Item, {
183
187
  eventKey: item.name,
@@ -188,7 +192,7 @@ function ObsColsList() {
188
192
  children: item.type
189
193
  })]
190
194
  }, item.name);
191
- }
195
+ }, []);
192
196
  const obsList = (0, _react.useMemo)(() => obsColsList.map(item => {
193
197
  if (item.type === "categorical") {
194
198
  return categoricalList(item, active);
@@ -197,7 +201,7 @@ function ObsColsList() {
197
201
  } else {
198
202
  return otherList(item, active);
199
203
  }
200
- }), [obsColsList, active]);
204
+ }), [obsColsList, categoricalList, active, continuousList, otherList]);
201
205
  if (!serverError) {
202
206
  return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
203
207
  className: "position-relative",
@@ -212,6 +216,10 @@ function ObsColsList() {
212
216
  type: "obsSelected",
213
217
  obs: obsColsList.find(obs => obs.name === key)
214
218
  });
219
+ dispatch({
220
+ type: "set.colorEncoding",
221
+ value: "obs"
222
+ });
215
223
  }
216
224
  },
217
225
  children: obsList
@@ -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,8 +5,9 @@ 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");
@@ -19,6 +20,7 @@ var _DatasetContext = require("../../context/DatasetContext");
19
20
  var _mapHelper = require("../../helpers/map-helper");
20
21
  var _zarrHelper = require("../../helpers/zarr-helper");
21
22
  var _colorHelper = require("../../helpers/color-helper");
23
+ var _LoadingSpinner = require("../../utils/LoadingSpinner");
22
24
  var _jsxRuntime = require("react/jsx-runtime");
23
25
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
24
26
  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 +49,232 @@ function ScatterplotControls() {
47
49
  })]
48
50
  });
49
51
  }
52
+ const INITIAL_VIEW_STATE = {
53
+ longitude: 0,
54
+ latitude: 0,
55
+ zoom: 0,
56
+ maxZoom: 16,
57
+ pitch: 0,
58
+ bearing: 0
59
+ };
60
+ const DEFAULT_DATA_POINT = {
61
+ value: null,
62
+ position: null,
63
+ color: null
64
+ };
50
65
  function Scatterplot(_ref) {
66
+ var _dataset$selectedObs;
51
67
  let {
52
68
  radius = 30
53
69
  } = _ref;
54
70
  const dataset = (0, _DatasetContext.useDataset)();
55
- const dispatch = (0, _DatasetContext.useDatasetDispatch)();
71
+ const {
72
+ getScale,
73
+ getColor
74
+ } = (0, _colorHelper.useColor)();
75
+ const [viewState, setViewState] = (0, _react.useState)(INITIAL_VIEW_STATE);
56
76
  const [features, setFeatures] = (0, _react.useState)({
57
77
  type: "FeatureCollection",
58
78
  features: []
59
79
  });
60
80
  const [mode, setMode] = (0, _react.useState)(() => _editModes.ViewMode);
61
81
  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
82
+ const [featureState, setFeatureState] = (0, _react.useState)([]);
83
+ const [scale, setScale] = (0, _react.useState)(() => getScale());
84
+ const [data, setData] = (0, _react.useState)([]);
85
+ const [obsmParams, setObsmParams] = (0, _react.useState)({
86
+ url: dataset.url,
87
+ path: "obsm/" + dataset.selectedObsm
73
88
  });
89
+ const [xParams, setXParams] = (0, _react.useState)({
90
+ url: dataset.url,
91
+ path: "X"
92
+ });
93
+ const [obsParams, setObsParams] = (0, _react.useState)({
94
+ url: dataset.url,
95
+ path: "obs/" + ((_dataset$selectedObs = dataset.selectedObs) === null || _dataset$selectedObs === void 0 ? void 0 : _dataset$selectedObs.name) + "/codes"
96
+ });
97
+
98
+ // needs to be wrapped in useMemo as it is an array an could cause an infinite loop otherwise
99
+ const xSelection = (0, _react.useMemo)(() => {
100
+ var _dataset$selectedVar;
101
+ return [null, (_dataset$selectedVar = dataset.selectedVar) === null || _dataset$selectedVar === void 0 ? void 0 : _dataset$selectedVar.matrix_index];
102
+ }, [dataset.selectedVar]);
103
+ const obsmData = (0, _zarrHelper.useZarr)(obsmParams, null, _zarrHelper.GET_OPTIONS);
104
+ const xData = (0, _zarrHelper.useZarr)(xParams, xSelection, _zarrHelper.GET_OPTIONS);
105
+ const obsData = (0, _zarrHelper.useZarr)(obsParams, null, _zarrHelper.GET_OPTIONS);
106
+ (0, _react.useEffect)(() => {
107
+ setObsmParams(p => {
108
+ return {
109
+ ...p,
110
+ path: "obsm/" + dataset.selectedObsm
111
+ };
112
+ });
113
+ }, [dataset.selectedObsm]);
114
+ (0, _react.useEffect)(() => {
115
+ setXParams(p => {
116
+ var _dataset$selectedVar2;
117
+ return {
118
+ ...p,
119
+ s: [null, (_dataset$selectedVar2 = dataset.selectedVar) === null || _dataset$selectedVar2 === void 0 ? void 0 : _dataset$selectedVar2.matrix_index]
120
+ };
121
+ });
122
+ }, [dataset.selectedVar]);
123
+ (0, _react.useEffect)(() => {
124
+ setObsParams(p => {
125
+ var _dataset$selectedObs2;
126
+ return {
127
+ ...p,
128
+ path: "obs/" + ((_dataset$selectedObs2 = dataset.selectedObs) === null || _dataset$selectedObs2 === void 0 ? void 0 : _dataset$selectedObs2.name) + "/codes"
129
+ };
130
+ });
131
+ }, [dataset.selectedObs]);
132
+ (0, _react.useEffect)(() => {
133
+ setObsmParams(p => {
134
+ return {
135
+ ...p,
136
+ url: dataset.url
137
+ };
138
+ });
139
+ setXParams(p => {
140
+ return {
141
+ ...p,
142
+ url: dataset.url
143
+ };
144
+ });
145
+ setObsParams(p => {
146
+ return {
147
+ ...p,
148
+ url: dataset.url
149
+ };
150
+ });
151
+ }, [dataset.url]);
152
+
153
+ // @TODO: assert length of obsmData, xData, obsData is equal
154
+
74
155
  (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;
156
+ if (!obsmData.isPending && !obsmData.serverError) {
157
+ setData(d => {
158
+ return _lodash.default.map(obsmData.data, (p, index) => {
159
+ return _lodash.default.defaults({
160
+ position: p
161
+ }, d === null || d === void 0 ? void 0 : d[index], DEFAULT_DATA_POINT);
162
+ });
163
+ });
164
+ const mapHelper = new _mapHelper.MapHelper();
165
+ const {
166
+ latitude,
167
+ longitude,
168
+ zoom
169
+ } = mapHelper.fitBounds(obsmData.data);
170
+ setViewState(v => {
80
171
  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)
172
+ ...v,
173
+ longitude: longitude,
174
+ latitude: latitude,
175
+ zoom: zoom
85
176
  };
86
177
  });
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);
178
+ } else if (!obsmData.isPending && obsmData.serverError) {
179
+ setData(d => {
180
+ return _lodash.default.map(d, e => {
181
+ return _lodash.default.defaults({
182
+ position: null
183
+ }, e, DEFAULT_DATA_POINT);
111
184
  });
112
- };
113
- fetchObsm().catch(console.error);
185
+ });
114
186
  }
115
- }, [dataset.url, dataset.selectedObsm]);
187
+ }, [dataset.selectedObsm, obsmData.data, obsmData.isPending, obsmData.serverError]);
116
188
  (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"
189
+ if (dataset.colorEncoding === "var") {
190
+ if (!xData.isPending && !xData.serverError) {
191
+ const s = getScale(xData.data);
192
+ setScale(() => s);
193
+ setData(d => {
194
+ return _lodash.default.map(xData.data, (v, index) => {
195
+ return _lodash.default.defaults({
196
+ value: v,
197
+ color: getColor(s, v)
198
+ }, d === null || d === void 0 ? void 0 : d[index], DEFAULT_DATA_POINT);
126
199
  });
127
200
  });
128
- };
129
- fetchData().catch(console.error);
201
+ } else if (!xData.isPending && xData.serverError) {
202
+ const s = getScale();
203
+ setScale(() => s);
204
+ setData(d => {
205
+ return _lodash.default.map(d, e => {
206
+ return _lodash.default.defaults({
207
+ value: null,
208
+ color: null
209
+ }, e, DEFAULT_DATA_POINT);
210
+ });
211
+ });
212
+ }
130
213
  }
131
- }, [dataset.url, dataset.selectedVar, dispatch]);
214
+ }, [dataset.colorEncoding, xData.data, xData.isPending, xData.serverError, getScale, getColor]);
132
215
  (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"
216
+ if (dataset.colorEncoding === "obs") {
217
+ if (!obsData.isPending && !obsData.serverError) {
218
+ const s = getScale(obsData.data);
219
+ setScale(() => s);
220
+ setData(d => {
221
+ return _lodash.default.map(obsData.data, (v, index) => {
222
+ return _lodash.default.defaults({
223
+ value: v,
224
+ color: getColor(s, v)
225
+ }, d === null || d === void 0 ? void 0 : d[index], DEFAULT_DATA_POINT);
226
+ });
227
+ });
228
+ } else if (!obsData.isPending && obsData.serverError) {
229
+ const s = getScale();
230
+ setScale(() => s);
231
+ setData(d => {
232
+ return _lodash.default.map(d, e => {
233
+ return _lodash.default.defaults({
234
+ value: null,
235
+ color: null
236
+ }, e, DEFAULT_DATA_POINT);
142
237
  });
143
238
  });
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
239
  }
179
- setSelectedFeatureIndexes(updatedSelectedFeatureIndexes); //now update your state
180
240
  }
181
- })];
241
+ }, [dataset.colorEncoding, obsData.data, obsData.isPending, obsData.serverError, getScale, getColor]);
242
+ const layers = (0, _react.useMemo)(() => {
243
+ return [new _layers.ScatterplotLayer({
244
+ id: "cherita-layer-scatterplot",
245
+ data: data,
246
+ radiusScale: radius,
247
+ radiusMinPixels: 1,
248
+ getPosition: d => d.position,
249
+ getFillColor: d => d.color,
250
+ getRadius: 1
251
+ }), new _layers2.EditableGeoJsonLayer({
252
+ id: "cherita-layer-draw",
253
+ data: features,
254
+ mode: mode,
255
+ selectedFeatureIndexes,
256
+ onEdit: _ref2 => {
257
+ let {
258
+ updatedData,
259
+ editType,
260
+ editContext
261
+ } = _ref2;
262
+ setFeatures(updatedData);
263
+ let updatedSelectedFeatureIndexes = selectedFeatureIndexes;
264
+ setFeatureState({
265
+ data: updatedData
266
+ });
267
+ if (editType === "addFeature") {
268
+ // when a drawing is complete, the value of editType becomes addFeature
269
+ const {
270
+ featureIndexes
271
+ } = editContext; //extracting indexes of current features selected
272
+ updatedSelectedFeatureIndexes = [...selectedFeatureIndexes, ...featureIndexes];
273
+ }
274
+ setSelectedFeatureIndexes(updatedSelectedFeatureIndexes); //now update your state
275
+ }
276
+ })];
277
+ }, [data, features, mode, radius, selectedFeatureIndexes]);
182
278
  function onLayerClick(info) {
183
279
  if (mode !== _editModes.ViewMode) {
184
280
  // don't change selection while editing
@@ -186,22 +282,23 @@ function Scatterplot(_ref) {
186
282
  }
187
283
  setSelectedFeatureIndexes(info.object ? [info.index] : []);
188
284
  }
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
- })
285
+
286
+ // @TODO: add error message
287
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
288
+ className: "cherita-scatterplot",
289
+ children: [(obsmData.isPending || xData.isPending || obsmData.isPending) && /*#__PURE__*/(0, _jsxRuntime.jsx)(_LoadingSpinner.LoadingSpinner, {}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_react2.default, {
290
+ viewState: viewState,
291
+ onViewStateChange: e => setViewState(e.viewState),
292
+ controller: true,
293
+ layers: layers,
294
+ onClick: onLayerClick
295
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_Toolbox.Toolbox, {
296
+ mode: mode,
297
+ setMode: setMode,
298
+ features: mode,
299
+ setFeatures: setFeatures
300
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_Legend.Legend, {
301
+ scale: scale
302
+ })]
206
303
  });
207
304
  }