@haniffalab/cherita-react 0.1.8 → 0.1.11

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/README.md CHANGED
@@ -1 +1,25 @@
1
- # react-wt.js
1
+ # Cherita
2
+
3
+ ## Development
4
+
5
+ Install [npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm)
6
+
7
+ Install packages
8
+
9
+ ```sh
10
+ npm i
11
+ ```
12
+
13
+ Create a ``.env`` file within ``sites/demo`` to store environment variables for Vite to use. Within it set ``VITE_API_URL`` to the backend API url like
14
+
15
+ ```sh
16
+ VITE_API_URL=http://localhost:5000/api/
17
+ ```
18
+
19
+ Run the demo app
20
+
21
+ ```sh
22
+ npm run start-demo
23
+ ```
24
+
25
+ The app will automatically reload when changes are made
@@ -0,0 +1,282 @@
1
+ "use strict";
2
+
3
+ function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.Dotplot = Dotplot;
8
+ exports.DotplotControls = DotplotControls;
9
+ require("bootstrap/dist/css/bootstrap.min.css");
10
+ var _Dropdown = _interopRequireDefault(require("react-bootstrap/Dropdown"));
11
+ var _react = _interopRequireWildcard(require("react"));
12
+ var _reactPlotly = _interopRequireDefault(require("react-plotly.js"));
13
+ var _lodash = _interopRequireDefault(require("lodash"));
14
+ var _DatasetContext = require("../../context/DatasetContext");
15
+ var _constants = require("../../constants/constants");
16
+ var _requests = require("../../utils/requests");
17
+ var _reactBootstrap = require("react-bootstrap");
18
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
19
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
20
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
21
+ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
22
+ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
23
+ 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; }
24
+ function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _typeof(key) === "symbol" ? key : String(key); }
25
+ function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
26
+ function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
27
+ function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
28
+ function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
29
+ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
30
+ function _iterableToArrayLimit(arr, i) { var _i = null == arr ? null : "undefined" != typeof Symbol && arr[Symbol.iterator] || arr["@@iterator"]; if (null != _i) { var _s, _e, _x, _r, _arr = [], _n = !0, _d = !1; try { if (_x = (_i = _i.call(arr)).next, 0 === i) { if (Object(_i) !== _i) return; _n = !1; } else for (; !(_n = (_s = _x.call(_i)).done) && (_arr.push(_s.value), _arr.length !== i); _n = !0); } catch (err) { _d = !0, _e = err; } finally { try { if (!_n && null != _i.return && (_r = _i.return(), Object(_r) !== _r)) return; } finally { if (_d) throw _e; } } return _arr; } }
31
+ function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
32
+ function DotplotControls() {
33
+ var dataset = (0, _DatasetContext.useDataset)();
34
+ var dispatch = (0, _DatasetContext.useDatasetDispatch)();
35
+ var _useState = (0, _react.useState)({
36
+ standardScale: dataset.controls.standardScale,
37
+ expressionCutoff: dataset.controls.expressionCutoff,
38
+ colorAxis: {
39
+ cmin: dataset.controls.colorAxis.cmin,
40
+ cmax: dataset.controls.colorAxis.cmax
41
+ }
42
+ }),
43
+ _useState2 = _slicedToArray(_useState, 2),
44
+ controls = _useState2[0],
45
+ setControls = _useState2[1];
46
+ (0, _react.useEffect)(function () {
47
+ setControls(function (c) {
48
+ return _objectSpread(_objectSpread({}, c), {}, {
49
+ colorAxis: {
50
+ cmin: dataset.controls.colorAxis.cmin,
51
+ cmax: dataset.controls.colorAxis.cmax
52
+ }
53
+ });
54
+ });
55
+ }, [dataset.controls.colorAxis.cmin, dataset.controls.colorAxis.cmax]);
56
+ var colorScaleList = _constants.PLOTLY_COLORSCALES.map(function (item) {
57
+ return /*#__PURE__*/_react.default.createElement(_Dropdown.default.Item, {
58
+ key: item,
59
+ active: dataset.controls.colorScale === item,
60
+ onClick: function onClick() {
61
+ dispatch({
62
+ type: "set.controls.colorScale",
63
+ colorScale: item
64
+ });
65
+ }
66
+ }, item);
67
+ });
68
+ var standardScaleList = _constants.DOTPLOT_STANDARDSCALES.map(function (item) {
69
+ return /*#__PURE__*/_react.default.createElement(_Dropdown.default.Item, {
70
+ key: item.value,
71
+ active: dataset.controls.standardScale === item.value,
72
+ onClick: function onClick() {
73
+ dispatch({
74
+ type: "set.controls.standardScale",
75
+ standardScale: item.value
76
+ });
77
+ }
78
+ }, item.name);
79
+ });
80
+ return /*#__PURE__*/_react.default.createElement(_reactBootstrap.ButtonToolbar, null, /*#__PURE__*/_react.default.createElement(_reactBootstrap.ButtonGroup, null, /*#__PURE__*/_react.default.createElement(_Dropdown.default, null, /*#__PURE__*/_react.default.createElement(_Dropdown.default.Toggle, {
81
+ id: "dropdownColorscale",
82
+ variant: "light"
83
+ }, dataset.controls.colorScale), /*#__PURE__*/_react.default.createElement(_Dropdown.default.Menu, null, colorScaleList))), /*#__PURE__*/_react.default.createElement(_reactBootstrap.ButtonGroup, null, /*#__PURE__*/_react.default.createElement(_reactBootstrap.InputGroup, null, /*#__PURE__*/_react.default.createElement(_reactBootstrap.InputGroup.Text, null, "Standard scale"), /*#__PURE__*/_react.default.createElement(_Dropdown.default, null, /*#__PURE__*/_react.default.createElement(_Dropdown.default.Toggle, {
84
+ id: "dropdownStandardScale",
85
+ variant: "light"
86
+ }, dataset.controls.standardScale), /*#__PURE__*/_react.default.createElement(_Dropdown.default.Menu, null, standardScaleList)))), /*#__PURE__*/_react.default.createElement(_reactBootstrap.ButtonGroup, null, /*#__PURE__*/_react.default.createElement(_reactBootstrap.ToggleButton, {
87
+ id: "toggleMeanOnlyExpressed",
88
+ type: "checkbox",
89
+ variant: "outline-primary",
90
+ checked: dataset.controls.meanOnlyExpressed,
91
+ onChange: function onChange() {
92
+ dispatch({
93
+ type: "set.controls.meanOnlyExpressed",
94
+ meanOnlyExpressed: !dataset.controls.meanOnlyExpressed
95
+ });
96
+ }
97
+ }, "Average only above cutoff")), /*#__PURE__*/_react.default.createElement(_reactBootstrap.Form, {
98
+ onSubmit: function onSubmit(e) {
99
+ e.preventDefault();
100
+ dispatch({
101
+ type: "set.controls.expressionCutoff",
102
+ expressionCutoff: parseFloat(controls.expressionCutoff)
103
+ });
104
+ }
105
+ }, /*#__PURE__*/_react.default.createElement(_reactBootstrap.InputGroup, null, /*#__PURE__*/_react.default.createElement(_reactBootstrap.InputGroup.Text, null, "Expression Cutoff"), /*#__PURE__*/_react.default.createElement(_reactBootstrap.Form.Control, {
106
+ size: "sm",
107
+ type: "number",
108
+ step: "0.1",
109
+ min: 0.0,
110
+ value: controls.expressionCutoff,
111
+ onChange: function onChange(e) {
112
+ setControls(_objectSpread(_objectSpread({}, controls), {}, {
113
+ expressionCutoff: e.target.value
114
+ }));
115
+ }
116
+ }), /*#__PURE__*/_react.default.createElement(_reactBootstrap.Button, {
117
+ type: "submit",
118
+ variant: "outline-primary"
119
+ }, "Apply"))), /*#__PURE__*/_react.default.createElement(_reactBootstrap.Form, {
120
+ onSubmit: function onSubmit(e) {
121
+ e.preventDefault();
122
+ dispatch({
123
+ type: "set.controls.colorAxis.crange",
124
+ cmin: controls.colorAxis.cmin,
125
+ cmax: controls.colorAxis.cmax
126
+ });
127
+ }
128
+ }, /*#__PURE__*/_react.default.createElement(_reactBootstrap.InputGroup, null, /*#__PURE__*/_react.default.createElement(_reactBootstrap.InputGroup.Text, null, "Colorscale"), /*#__PURE__*/_react.default.createElement(_reactBootstrap.InputGroup.Text, null, "min"), /*#__PURE__*/_react.default.createElement(_reactBootstrap.Form.Control, {
129
+ name: "scaleMin",
130
+ size: "sm",
131
+ type: "number",
132
+ value: controls.colorAxis.cmin,
133
+ step: 0.1,
134
+ min: Math.min(dataset.controls.colorAxis.dmin, 0.0),
135
+ max: dataset.controls.colorAxis.dmax,
136
+ onChange: function onChange(e) {
137
+ setControls(_objectSpread(_objectSpread({}, controls), {}, {
138
+ colorAxis: _objectSpread(_objectSpread({}, controls.colorAxis), {}, {
139
+ cmin: e.target.value
140
+ })
141
+ }));
142
+ }
143
+ }), /*#__PURE__*/_react.default.createElement(_reactBootstrap.InputGroup.Text, null, "max"), /*#__PURE__*/_react.default.createElement(_reactBootstrap.Form.Control, {
144
+ name: "scaleMax",
145
+ size: "sm",
146
+ type: "number",
147
+ value: controls.colorAxis.cmax,
148
+ step: 0.1,
149
+ min: controls.colorAxis.cmin,
150
+ max: dataset.controls.colorAxis.dmax,
151
+ onChange: function onChange(e) {
152
+ if (parseFloat(e.target.value) > dataset.controls.colorAxis.dmax) {
153
+ e.target.value = dataset.controls.colorAxis.dmax.toFixed(1);
154
+ }
155
+ setControls(_objectSpread(_objectSpread({}, controls), {}, {
156
+ colorAxis: _objectSpread(_objectSpread({}, controls.colorAxis), {}, {
157
+ cmax: e.target.value
158
+ })
159
+ }));
160
+ }
161
+ }), /*#__PURE__*/_react.default.createElement(_reactBootstrap.Button, {
162
+ type: "submit",
163
+ variant: "outline-primary"
164
+ }, "Apply"), /*#__PURE__*/_react.default.createElement(_reactBootstrap.Button, {
165
+ variant: "outline-primary",
166
+ onClick: function onClick() {
167
+ dispatch({
168
+ type: "set.controls.colorAxis.crange",
169
+ cmin: dataset.controls.colorAxis.dmin,
170
+ cmax: dataset.controls.colorAxis.dmax
171
+ });
172
+ }
173
+ }, "Autoscale"))));
174
+ }
175
+ function Dotplot() {
176
+ var dataset = (0, _DatasetContext.useDataset)();
177
+ var dispatch = (0, _DatasetContext.useDatasetDispatch)();
178
+ var colorscale = (0, _react.useRef)(dataset.controls.colorScale);
179
+ var _useState3 = (0, _react.useState)([]),
180
+ _useState4 = _slicedToArray(_useState3, 2),
181
+ data = _useState4[0],
182
+ setData = _useState4[1];
183
+ var _useState5 = (0, _react.useState)({}),
184
+ _useState6 = _slicedToArray(_useState5, 2),
185
+ layout = _useState6[0],
186
+ setLayout = _useState6[1];
187
+ var _useState7 = (0, _react.useState)(false),
188
+ _useState8 = _slicedToArray(_useState7, 2),
189
+ hasSelections = _useState8[0],
190
+ setHasSelections = _useState8[1];
191
+ // @TODO: set default scale
192
+
193
+ var updateColorscale = (0, _react.useCallback)(function (colorscale) {
194
+ setLayout(function (l) {
195
+ return _objectSpread(_objectSpread({}, l), {}, {
196
+ coloraxis: _objectSpread(_objectSpread({}, l.coloraxis), {}, {
197
+ colorscale: colorscale
198
+ })
199
+ });
200
+ });
201
+ }, []);
202
+ var update = (0, _react.useMemo)(function () {
203
+ var func = function func(abortController) {
204
+ if (dataset.selectedObs && dataset.selectedMultiVar.length) {
205
+ setHasSelections(true);
206
+ (0, _requests.fetchData)("dotplot", {
207
+ url: dataset.url,
208
+ selectedObs: dataset.selectedObs,
209
+ selectedMultiVar: dataset.selectedMultiVar.map(function (i) {
210
+ return i.name;
211
+ }),
212
+ standardScale: dataset.controls.standardScale,
213
+ meanOnlyExpressed: dataset.controls.meanOnlyExpressed,
214
+ expressionCutoff: dataset.controls.expressionCutoff
215
+ }, abortController.signal).then(function (data) {
216
+ setData(data.data);
217
+ setLayout(data.layout);
218
+ dispatch({
219
+ type: "set.controls.colorAxis",
220
+ colorAxis: {
221
+ dmin: data.range.min.toFixed(1),
222
+ dmax: data.range.max.toFixed(1),
223
+ cmin: data.range.min.toFixed(1),
224
+ cmax: data.range.max.toFixed(1)
225
+ }
226
+ });
227
+ updateColorscale(colorscale.current);
228
+ }).catch(function (response) {
229
+ if (response.name !== "AbortError") {
230
+ response.json().then(function (json) {
231
+ console.log(json.message);
232
+ });
233
+ }
234
+ });
235
+ } else {
236
+ setHasSelections(false);
237
+ }
238
+ };
239
+ // delay invoking the fetch function to avoid firing requests
240
+ // while dependencies might still be getting updated by the user
241
+ return _lodash.default.debounce(func, 500);
242
+ }, [dataset.url, dataset.selectedObs, dataset.selectedMultiVar, dataset.controls.standardScale, dataset.controls.meanOnlyExpressed, dataset.controls.expressionCutoff, updateColorscale, dispatch]);
243
+ (0, _react.useEffect)(function () {
244
+ // create an abort controller to pass into each fetch function
245
+ // to abort previous incompleted requests when a new request is fired
246
+ var abortController = new AbortController();
247
+ update(abortController);
248
+ return function () {
249
+ abortController.abort();
250
+ };
251
+ }, [update]);
252
+ (0, _react.useEffect)(function () {
253
+ colorscale.current = dataset.controls.colorScale;
254
+ updateColorscale(colorscale.current);
255
+ }, [dataset.controls.colorScale, updateColorscale]);
256
+ (0, _react.useEffect)(function () {
257
+ setLayout(function (l) {
258
+ return _objectSpread(_objectSpread({}, l), {}, {
259
+ coloraxis: _objectSpread(_objectSpread({}, l.coloraxis), {}, {
260
+ cmin: dataset.controls.colorAxis.cmin,
261
+ cmax: dataset.controls.colorAxis.cmax
262
+ })
263
+ });
264
+ });
265
+ }, [dataset.controls.colorAxis.cmin, dataset.controls.colorAxis.cmax]);
266
+ if (hasSelections) {
267
+ return /*#__PURE__*/_react.default.createElement("div", {
268
+ className: "cherita-dotplot"
269
+ }, /*#__PURE__*/_react.default.createElement(_reactPlotly.default, {
270
+ data: data,
271
+ layout: layout,
272
+ useResizeHandler: true,
273
+ style: {
274
+ maxWidth: "100%",
275
+ maxHeight: "100%"
276
+ }
277
+ }));
278
+ }
279
+ return /*#__PURE__*/_react.default.createElement("div", {
280
+ className: "cherita-dotplot"
281
+ }, /*#__PURE__*/_react.default.createElement("p", null, "Select OBS and VAR"));
282
+ }
@@ -4,14 +4,16 @@ function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" =
4
4
  Object.defineProperty(exports, "__esModule", {
5
5
  value: true
6
6
  });
7
- exports.Dotplot = Dotplot;
8
- exports.DotplotControls = DotplotControls;
7
+ exports.Heatmap = Heatmap;
8
+ exports.HeatmapControls = HeatmapControls;
9
9
  require("bootstrap/dist/css/bootstrap.min.css");
10
10
  var _Dropdown = _interopRequireDefault(require("react-bootstrap/Dropdown"));
11
11
  var _react = _interopRequireWildcard(require("react"));
12
12
  var _reactPlotly = _interopRequireDefault(require("react-plotly.js"));
13
- var _DatasetContext = require("../context/DatasetContext");
14
- var _constants = require("../constants/constants");
13
+ var _lodash = _interopRequireDefault(require("lodash"));
14
+ var _DatasetContext = require("../../context/DatasetContext");
15
+ var _constants = require("../../constants/constants");
16
+ var _requests = require("../../utils/requests");
15
17
  function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
16
18
  function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
17
19
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
@@ -26,24 +28,17 @@ function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o =
26
28
  function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
27
29
  function _iterableToArrayLimit(arr, i) { var _i = null == arr ? null : "undefined" != typeof Symbol && arr[Symbol.iterator] || arr["@@iterator"]; if (null != _i) { var _s, _e, _x, _r, _arr = [], _n = !0, _d = !1; try { if (_x = (_i = _i.call(arr)).next, 0 === i) { if (Object(_i) !== _i) return; _n = !1; } else for (; !(_n = (_s = _x.call(_i)).done) && (_arr.push(_s.value), _arr.length !== i); _n = !0); } catch (err) { _d = !0, _e = err; } finally { try { if (!_n && null != _i.return && (_r = _i.return(), Object(_r) !== _r)) return; } finally { if (_d) throw _e; } } return _arr; } }
28
30
  function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
29
- function DotplotControls() {
31
+ function HeatmapControls() {
30
32
  var dataset = (0, _DatasetContext.useDataset)();
31
33
  var dispatch = (0, _DatasetContext.useDatasetDispatch)();
32
- var _useState = (0, _react.useState)(dataset.colorscale),
33
- _useState2 = _slicedToArray(_useState, 2),
34
- active = _useState2[0],
35
- setActive = _useState2[1];
36
- (0, _react.useEffect)(function () {
37
- setActive(dataset.colorscale);
38
- }, [dataset.colorscale]);
39
34
  var colormapList = _constants.PLOTLY_COLORSCALES.map(function (item) {
40
35
  return /*#__PURE__*/_react.default.createElement(_Dropdown.default.Item, {
41
36
  key: item,
42
- active: active === item,
37
+ active: dataset.controls.colorScale === item,
43
38
  onClick: function onClick() {
44
39
  dispatch({
45
- type: "colorscaleSelected",
46
- colorscale: item
40
+ type: "set.controls.colorScale",
41
+ colorScale: item
47
42
  });
48
43
  }
49
44
  }, item);
@@ -51,23 +46,23 @@ function DotplotControls() {
51
46
  return /*#__PURE__*/_react.default.createElement(_Dropdown.default, null, /*#__PURE__*/_react.default.createElement(_Dropdown.default.Toggle, {
52
47
  id: "dropdownColorscale",
53
48
  variant: "light"
54
- }, dataset.colorscale), /*#__PURE__*/_react.default.createElement(_Dropdown.default.Menu, null, colormapList));
49
+ }, dataset.controls.colorScale), /*#__PURE__*/_react.default.createElement(_Dropdown.default.Menu, null, colormapList));
55
50
  }
56
- function Dotplot() {
51
+ function Heatmap() {
57
52
  var dataset = (0, _DatasetContext.useDataset)();
58
- var colorscale = (0, _react.useRef)(dataset.colorscale);
59
- var _useState3 = (0, _react.useState)([]),
53
+ var colorscale = (0, _react.useRef)(dataset.controls.colorScale);
54
+ var _useState = (0, _react.useState)([]),
55
+ _useState2 = _slicedToArray(_useState, 2),
56
+ data = _useState2[0],
57
+ setData = _useState2[1];
58
+ var _useState3 = (0, _react.useState)({}),
60
59
  _useState4 = _slicedToArray(_useState3, 2),
61
- data = _useState4[0],
62
- setData = _useState4[1];
63
- var _useState5 = (0, _react.useState)({}),
60
+ layout = _useState4[0],
61
+ setLayout = _useState4[1];
62
+ var _useState5 = (0, _react.useState)(false),
64
63
  _useState6 = _slicedToArray(_useState5, 2),
65
- layout = _useState6[0],
66
- setLayout = _useState6[1];
67
- var _useState7 = (0, _react.useState)(false),
68
- _useState8 = _slicedToArray(_useState7, 2),
69
- hasSelections = _useState8[0],
70
- setHasSelections = _useState8[1];
64
+ hasSelections = _useState6[0],
65
+ setHasSelections = _useState6[1];
71
66
  var updateColorscale = (0, _react.useCallback)(function (colorscale) {
72
67
  setLayout(function (l) {
73
68
  return _objectSpread(_objectSpread({}, l), {}, {
@@ -77,51 +72,62 @@ function Dotplot() {
77
72
  });
78
73
  });
79
74
  }, []);
80
- (0, _react.useEffect)(function () {
81
- if (dataset.selectedObs && dataset.selectedMultiVar.length) {
82
- setHasSelections(true);
83
- fetch(new URL("dotplot", process.env.REACT_APP_API_URL), {
84
- method: "POST",
85
- mode: "cors",
86
- headers: {
87
- "Content-Type": "application/json",
88
- Accept: "application/json"
89
- },
90
- body: JSON.stringify({
75
+ var update = (0, _react.useMemo)(function () {
76
+ var func = function func(abortController) {
77
+ if (dataset.selectedObs && dataset.selectedMultiVar.length) {
78
+ setHasSelections(true);
79
+ (0, _requests.fetchData)("heatmap", {
91
80
  url: dataset.url,
92
81
  selectedObs: dataset.selectedObs,
93
- selectedMultiVar: dataset.selectedMultiVar
94
- })
95
- }).then(function (response) {
96
- return response.json();
97
- }).then(function (data) {
98
- setData(data.data);
99
- setLayout(data.layout);
100
- updateColorscale(colorscale.current);
101
- });
102
- } else {
103
- setHasSelections(false);
104
- }
105
- }, [dataset.url, dataset.selectedObs, dataset.selectedMultiVar, updateColorscale]);
82
+ selectedMultiVar: dataset.selectedMultiVar.map(function (i) {
83
+ return i.name;
84
+ })
85
+ }, abortController.signal).then(function (data) {
86
+ setData(data.data);
87
+ setLayout(data.layout);
88
+ updateColorscale(colorscale.current);
89
+ }).catch(function (response) {
90
+ if (response.name !== "AbortError") {
91
+ response.json().then(function (json) {
92
+ console.log(json.message);
93
+ });
94
+ }
95
+ });
96
+ } else {
97
+ setHasSelections(false);
98
+ }
99
+ };
100
+ // delay invoking the fetch function to avoid firing requests
101
+ // while dependencies might still be getting updated by the user
102
+ return _lodash.default.debounce(func, 500);
103
+ }, [dataset.selectedMultiVar, dataset.selectedObs, dataset.url, updateColorscale]);
104
+ (0, _react.useEffect)(function () {
105
+ // create an abort controller to pass into each fetch function
106
+ // to abort previous incompleted requests when a new request is fired
107
+ var abortController = new AbortController();
108
+ update(abortController);
109
+ return function () {
110
+ abortController.abort();
111
+ };
112
+ }, [update]);
106
113
  (0, _react.useEffect)(function () {
107
- console.log("update colorscale");
108
- colorscale.current = dataset.colorscale;
114
+ colorscale.current = dataset.controls.colorScale;
109
115
  updateColorscale(colorscale.current);
110
- }, [dataset.colorscale, updateColorscale]);
116
+ }, [dataset.controls.colorScale, updateColorscale]);
111
117
  if (hasSelections) {
112
118
  return /*#__PURE__*/_react.default.createElement("div", {
113
- className: "container text-center"
114
- }, /*#__PURE__*/_react.default.createElement("h5", null, dataset.url), /*#__PURE__*/_react.default.createElement(DotplotControls, null), /*#__PURE__*/_react.default.createElement(_reactPlotly.default, {
119
+ className: "cherita-heatmap"
120
+ }, /*#__PURE__*/_react.default.createElement(_reactPlotly.default, {
115
121
  data: data,
116
122
  layout: layout,
117
123
  useResizeHandler: true,
118
124
  style: {
119
- width: "100%",
120
- height: "100%"
125
+ maxWidth: "100%",
126
+ maxHeight: "100%"
121
127
  }
122
128
  }));
123
129
  }
124
130
  return /*#__PURE__*/_react.default.createElement("div", {
125
- className: "h-100"
126
- }, /*#__PURE__*/_react.default.createElement("h5", null, dataset.url), /*#__PURE__*/_react.default.createElement("p", null, "Select OBS and VAR"));
131
+ className: "cherita-heatmap"
132
+ }, /*#__PURE__*/_react.default.createElement("p", null, "Select OBS and VAR"));
127
133
  }