@complat/react-spectra-editor 1.2.1 → 1.3.1

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.
@@ -8,7 +8,18 @@ require("@testing-library/jest-dom");
8
8
  var _r08_change_axes = _interopRequireDefault(require("../../../../components/cmd_bar/r08_change_axes"));
9
9
  var _list_layout = require("../../../../constants/list_layout");
10
10
  const mockStore = (0, _reduxMockStore.default)([]);
11
- const store = mockStore({});
11
+ const store = mockStore({
12
+ axesUnits: {
13
+ axes: [{
14
+ xUnit: '',
15
+ yUnit: ''
16
+ }]
17
+ },
18
+ curve: {
19
+ curveIdx: 0
20
+ },
21
+ layout: _list_layout.LIST_LAYOUT.CYCLIC_VOLTAMMETRY
22
+ });
12
23
  const dispatchMock = () => Promise.resolve({});
13
24
  store.dispatch = jest.fn(dispatchMock);
14
25
  const options = ['Voltage in V', 'Voltage vs Ref in V', 'Potential in V', 'Potential vs Ref in V'];
@@ -35,14 +35,17 @@ const setRef = (classes, cyclicVotaSt, curveIdx, setCylicVoltaRefFactorAct) => {
35
35
  } = cyclicVotaSt;
36
36
  const spectra = spectraList[curveIdx];
37
37
  let refFactor = 0.0;
38
+ let hasRefPeaks = false;
38
39
  if (spectra) {
39
40
  const {
40
- shift
41
+ shift,
42
+ hasRefPeak
41
43
  } = spectra;
42
44
  const {
43
45
  val
44
46
  } = shift;
45
47
  refFactor = val;
48
+ hasRefPeaks = hasRefPeak;
46
49
  }
47
50
  const onFactorChanged = e => setCylicVoltaRefFactorAct({
48
51
  factor: e.target.value,
@@ -67,7 +70,7 @@ const setRef = (classes, cyclicVotaSt, curveIdx, setCylicVoltaRefFactorAct) => {
67
70
  },
68
71
  label: /*#__PURE__*/_react.default.createElement("span", {
69
72
  className: (0, _classnames.default)(classes.txtLabel, 'txtfield-sv-bar-label')
70
- }, "Ref Value (V)"),
73
+ }, hasRefPeaks ? 'Ref Value (V)' : 'Shift'),
71
74
  variant: "outlined",
72
75
  onChange: onFactorChanged,
73
76
  onBlur: onFactorChanged,
@@ -95,6 +98,17 @@ const Pecker = _ref => {
95
98
  const onConfirmSetRef = () => setCylicVoltaRefAct({
96
99
  jcampIdx: curveIdx
97
100
  });
101
+ const {
102
+ spectraList
103
+ } = cyclicVotaSt;
104
+ const spectra = spectraList[curveIdx];
105
+ let hasRefPeaks = false;
106
+ if (spectra) {
107
+ const {
108
+ hasRefPeak
109
+ } = spectra;
110
+ hasRefPeaks = hasRefPeak;
111
+ }
98
112
  return !_cfg.default.hidePanelCyclicVolta(layoutSt) ? /*#__PURE__*/_react.default.createElement("span", {
99
113
  "data-testid": "Pecker"
100
114
  }, /*#__PURE__*/_react.default.createElement(_Tooltip.default, {
@@ -118,7 +132,7 @@ const Pecker = _ref => {
118
132
  }, "I", /*#__PURE__*/_react.default.createElement("sub", null, "\u03BB0"), "-")))), setRef(classes, cyclicVotaSt, curveIdx, setCylicVoltaRefFactorAct), /*#__PURE__*/_react.default.createElement(_Tooltip.default, {
119
133
  title: /*#__PURE__*/_react.default.createElement("span", {
120
134
  className: "txt-sv-tp"
121
- }, "Set Reference")
135
+ }, hasRefPeaks ? 'Set Reference' : 'Set Shift')
122
136
  }, /*#__PURE__*/_react.default.createElement("span", null, /*#__PURE__*/_react.default.createElement(_common.MuButton, {
123
137
  className: (0, _classnames.default)((0, _common.focusStyle)(isFocusSetRefSt, classes), 'btn-sv-bar-setref'),
124
138
  onClick: onConfirmSetRef
@@ -29,13 +29,29 @@ const styles = () => Object.assign({
29
29
  width: 100
30
30
  }
31
31
  }, _common.commonStyle);
32
- const axisX = (classes, layoutSt, axesUnitsSt, updateXAxisAct) => {
32
+ const axisX = (classes, layoutSt, axesUnitsSt, updateXAxisAct, curveSt) => {
33
33
  const optionsAxisX = _list_axes.LIST_AXES.x;
34
34
  const options = optionsAxisX[layoutSt];
35
- const onChange = e => updateXAxisAct(e.target.value);
36
35
  const {
37
- xUnit
36
+ curveIdx
37
+ } = curveSt;
38
+ const onChange = e => updateXAxisAct({
39
+ value: e.target.value,
40
+ curveIndex: curveIdx
41
+ });
42
+ const {
43
+ axes
38
44
  } = axesUnitsSt;
45
+ let selectedAxes = axes[curveIdx];
46
+ if (!selectedAxes) {
47
+ selectedAxes = {
48
+ xUnit: '',
49
+ yUnit: ''
50
+ };
51
+ }
52
+ const {
53
+ xUnit
54
+ } = selectedAxes;
39
55
  return /*#__PURE__*/_react.default.createElement(_material.FormControl, {
40
56
  className: (0, _classnames.default)(classes.fieldLayout),
41
57
  variant: "outlined"
@@ -58,15 +74,30 @@ const axisX = (classes, layoutSt, axesUnitsSt, updateXAxisAct) => {
58
74
  className: (0, _classnames.default)(classes.txtLabelTopInput)
59
75
  }, "x-Axis"));
60
76
  };
61
- const axisY = (classes, layoutSt, axesUnitsSt, updateYAxisAct) => {
77
+ const axisY = (classes, layoutSt, axesUnitsSt, updateYAxisAct, curveSt) => {
62
78
  const optionsAxisX = _list_axes.LIST_AXES.y;
63
79
  const options = optionsAxisX[layoutSt];
64
- const onChange = e => updateYAxisAct(e.target.value);
65
80
  const {
66
- yUnit
81
+ curveIdx
82
+ } = curveSt;
83
+ const onChange = e => updateYAxisAct({
84
+ value: e.target.value,
85
+ curveIndex: curveIdx
86
+ });
87
+ const {
88
+ axes
67
89
  } = axesUnitsSt;
90
+ let selectedAxes = axes[curveIdx];
91
+ if (!selectedAxes) {
92
+ selectedAxes = {
93
+ xUnit: '',
94
+ yUnit: ''
95
+ };
96
+ }
97
+ const {
98
+ yUnit
99
+ } = selectedAxes;
68
100
  return /*#__PURE__*/_react.default.createElement(_material.FormControl, {
69
- "data-testid": "ChangeAxes",
70
101
  className: (0, _classnames.default)(classes.fieldLayout),
71
102
  variant: "outlined"
72
103
  }, /*#__PURE__*/_react.default.createElement(_material.Select, {
@@ -88,11 +119,11 @@ const axisY = (classes, layoutSt, axesUnitsSt, updateYAxisAct) => {
88
119
  className: (0, _classnames.default)(classes.txtLabelTopInput)
89
120
  }, "y-Axis"));
90
121
  };
91
- const showSelect = (classes, layoutSt, curveSt, axesUnitsSt, updateXAxisAct, updateYAxisActt) => {
122
+ const showSelect = (classes, layoutSt, curveSt, axesUnitsSt, updateXAxisAct, updateYAxisAct) => {
92
123
  if (!listLayoutToShow.includes(layoutSt)) {
93
124
  return /*#__PURE__*/_react.default.createElement("i", null);
94
125
  }
95
- return /*#__PURE__*/_react.default.createElement("span", null, axisX(classes, layoutSt, axesUnitsSt, updateXAxisAct), axisY(classes, layoutSt, axesUnitsSt, updateYAxisActt));
126
+ return /*#__PURE__*/_react.default.createElement("span", null, axisX(classes, layoutSt, axesUnitsSt, updateXAxisAct, curveSt), axisY(classes, layoutSt, axesUnitsSt, updateYAxisAct, curveSt));
96
127
  };
97
128
  const ChangeAxes = _ref => {
98
129
  let {
@@ -122,7 +153,7 @@ const mapDispatchToProps = dispatch => (0, _redux.bindActionCreators)({
122
153
  ChangeAxes.propTypes = {
123
154
  classes: _propTypes.default.object.isRequired,
124
155
  layoutSt: _propTypes.default.string.isRequired,
125
- curveSt: _propTypes.default.string.isRequired,
156
+ curveSt: _propTypes.default.object.isRequired,
126
157
  axesUnitsSt: _propTypes.default.object.isRequired,
127
158
  updateXAxisAct: _propTypes.default.func.isRequired,
128
159
  updateYAxisAct: _propTypes.default.func.isRequired
@@ -68,10 +68,13 @@ class ViewerLine extends _react.default.Component {
68
68
  let xxLabel = xLabel;
69
69
  let yyLabel = yLabel;
70
70
  if (axesUnitsSt) {
71
+ const {
72
+ axes
73
+ } = axesUnitsSt;
71
74
  const {
72
75
  xUnit,
73
76
  yUnit
74
- } = axesUnitsSt;
77
+ } = axes[0];
75
78
  xxLabel = xUnit === '' ? xLabel : xUnit;
76
79
  yyLabel = yUnit === '' ? yLabel : yUnit;
77
80
  }
@@ -123,10 +126,13 @@ class ViewerLine extends _react.default.Component {
123
126
  let xxLabel = xLabel;
124
127
  let yyLabel = yLabel;
125
128
  if (axesUnitsSt) {
129
+ const {
130
+ axes
131
+ } = axesUnitsSt;
126
132
  const {
127
133
  xUnit,
128
134
  yUnit
129
- } = axesUnitsSt;
135
+ } = axes[0];
130
136
  xxLabel = xUnit === '' ? xLabel : xUnit;
131
137
  yyLabel = yUnit === '' ? yLabel : yUnit;
132
138
  }
@@ -69,10 +69,23 @@ class ViewerMulti extends _react.default.Component {
69
69
  let xxLabel = xLabel;
70
70
  let yyLabel = yLabel;
71
71
  if (axesUnitsSt) {
72
+ const {
73
+ curveIdx
74
+ } = curveSt;
75
+ const {
76
+ axes
77
+ } = axesUnitsSt;
78
+ let selectedAxes = axes[curveIdx];
79
+ if (!selectedAxes) {
80
+ selectedAxes = {
81
+ xUnit: '',
82
+ yUnit: ''
83
+ };
84
+ }
72
85
  const {
73
86
  xUnit,
74
87
  yUnit
75
- } = axesUnitsSt;
88
+ } = selectedAxes;
76
89
  xxLabel = xUnit === '' ? xLabel : xUnit;
77
90
  yyLabel = yUnit === '' ? yLabel : yUnit;
78
91
  }
@@ -122,10 +135,23 @@ class ViewerMulti extends _react.default.Component {
122
135
  let xxLabel = xLabel;
123
136
  let yyLabel = yLabel;
124
137
  if (axesUnitsSt) {
138
+ const {
139
+ curveIdx
140
+ } = curveSt;
141
+ const {
142
+ axes
143
+ } = axesUnitsSt;
144
+ let selectedAxes = axes[curveIdx];
145
+ if (!selectedAxes) {
146
+ selectedAxes = {
147
+ xUnit: '',
148
+ yUnit: ''
149
+ };
150
+ }
125
151
  const {
126
152
  xUnit,
127
153
  yUnit
128
- } = axesUnitsSt;
154
+ } = selectedAxes;
129
155
  xxLabel = xUnit === '' ? xLabel : xUnit;
130
156
  yyLabel = yUnit === '' ? yLabel : yUnit;
131
157
  }
@@ -388,6 +388,29 @@ class MultiFocus {
388
388
  yt
389
389
  } = (0, _compass.TfRescale)(this);
390
390
  const dPks = this.mergedPeaks(editPeakSt);
391
+ const {
392
+ spectraList
393
+ } = this.cyclicvoltaSt;
394
+ const spectra = spectraList[this.jcampIdx];
395
+ let indexOfCVRefPeaks = [];
396
+ if (spectra) {
397
+ const {
398
+ shift,
399
+ hasRefPeak
400
+ } = spectra;
401
+ const {
402
+ ref
403
+ } = shift;
404
+ if (ref && hasRefPeak) {
405
+ const {
406
+ min,
407
+ max
408
+ } = ref;
409
+ indexOfCVRefPeaks = dPks.map((p, index) => {
410
+ return p === min || p === max ? -1 : index;
411
+ });
412
+ }
413
+ }
391
414
  const mpp = this.tags.pPath.selectAll('path').data(dPks);
392
415
  mpp.exit().attr('class', 'exit').remove();
393
416
  const linePath = [{
@@ -404,7 +427,25 @@ class MultiFocus {
404
427
  y: 10
405
428
  }];
406
429
  const lineSymbol = d3.line().x(d => d.x).y(d => d.y)(linePath);
407
- mpp.enter().append('path').attr('d', lineSymbol).attr('class', 'enter-peak').attr('fill', 'red').attr('stroke', 'pink').attr('stroke-width', 3).attr('stroke-opacity', 0.0).merge(mpp).attr('id', d => `mpp${Math.round(1000 * d.x)}`).attr('transform', d => `translate(${xt(d.x)}, ${yt(d.y)})`).on('mouseover', (event, d) => {
430
+ const lineRefPath = [{
431
+ x: -0.5,
432
+ y: 10
433
+ }, {
434
+ x: -4,
435
+ y: -20
436
+ }, {
437
+ x: 4,
438
+ y: -20
439
+ }, {
440
+ x: 0.5,
441
+ y: 10
442
+ }];
443
+ const lineSymbolRef = d3.line().x(d => d.x).y(d => d.y)(lineRefPath);
444
+ mpp.enter().append('path').attr('d', (_, index) => {
445
+ return indexOfCVRefPeaks[index] === -1 ? lineSymbolRef : lineSymbol;
446
+ }).attr('class', 'enter-peak').attr('fill', (_, index) => {
447
+ return indexOfCVRefPeaks[index] === -1 ? 'blue' : 'red';
448
+ }).attr('stroke', 'pink').attr('stroke-width', 3).attr('stroke-opacity', 0.0).merge(mpp).attr('id', d => `mpp${Math.round(1000 * d.x)}`).attr('transform', d => `translate(${xt(d.x)}, ${yt(d.y)})`).on('mouseover', (event, d) => {
408
449
  d3.select(`#mpp${Math.round(1000 * d.x)}`).attr('stroke-opacity', '1.0');
409
450
  d3.select(`#bpt${Math.round(1000 * d.x)}`).style('fill', 'blue');
410
451
  const tipParams = {
@@ -427,6 +468,12 @@ class MultiFocus {
427
468
  bpTxt.exit().attr('class', 'exit').remove();
428
469
  bpTxt.enter().append('text').attr('class', 'peak-text').attr('font-family', 'Helvetica').style('font-size', '12px').attr('fill', '#228B22').style('text-anchor', 'middle').merge(bpTxt).attr('id', d => `mpp${Math.round(1000 * d.x)}`).text(d => d.x.toFixed(2)).attr('transform', d => `translate(${xt(d.x)}, ${yt(d.y) - 25})`).on('click', (event, d) => this.onClickTarget(event, d));
429
470
  }
471
+ mpp.attr('fill', (_, index) => {
472
+ return indexOfCVRefPeaks[index] === -1 ? 'blue' : 'red';
473
+ });
474
+ mpp.attr('d', (_, index) => {
475
+ return indexOfCVRefPeaks[index] === -1 ? lineSymbolRef : lineSymbol;
476
+ });
430
477
  }
431
478
  drawPeckers() {
432
479
  const {
@@ -188,10 +188,10 @@ const CyclicVoltammetryPanel = _ref => {
188
188
  }, "Ref"), /*#__PURE__*/_react.default.createElement(_material.TableCell, {
189
189
  align: "left",
190
190
  className: (0, _classnames.default)(classes.tTxt, classes.square, 'txt-sv-panel-txt')
191
- }, "Ox"), /*#__PURE__*/_react.default.createElement(_material.TableCell, {
191
+ }, "Anodic"), /*#__PURE__*/_react.default.createElement(_material.TableCell, {
192
192
  align: "left",
193
193
  className: (0, _classnames.default)(classes.tTxt, classes.square, 'txt-sv-panel-txt')
194
- }, "Red"), /*#__PURE__*/_react.default.createElement(_material.TableCell, {
194
+ }, "Cathodic"), /*#__PURE__*/_react.default.createElement(_material.TableCell, {
195
195
  align: "left",
196
196
  className: (0, _classnames.default)(classes.tTxt, classes.square, 'txt-sv-panel-txt')
197
197
  }, "I ", /*#__PURE__*/_react.default.createElement("sub", null, "\u03BB0"), /*#__PURE__*/_react.default.createElement(_material.Tooltip, {
@@ -16,7 +16,7 @@ var _material = require("@mui/material");
16
16
  var _curve = require("../../actions/curve");
17
17
  var _list_layout = require("../../constants/list_layout");
18
18
  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
- 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; }
19
+ function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
20
20
  /* eslint-disable react/function-component-definition, function-paren-newline,
21
21
  react/require-default-props, react/no-unused-prop-types */
22
22
 
@@ -17,7 +17,7 @@ var _ExpandMore = _interopRequireDefault(require("@mui/icons-material/ExpandMore
17
17
  var _styles = require("@mui/styles");
18
18
  var _format = _interopRequireDefault(require("../../helpers/format"));
19
19
  /* eslint-disable no-mixed-operators, react/function-component-definition,
20
- react/require-default-props */
20
+ react/require-default-props, max-len */
21
21
 
22
22
  const styles = () => ({
23
23
  chip: {
@@ -109,7 +109,61 @@ const aucValue = integration => {
109
109
  }
110
110
  return values.join(', ');
111
111
  };
112
- const InfoPanel = _ref => {
112
+ const SECData = _ref => {
113
+ let {
114
+ classes,
115
+ layout,
116
+ detector,
117
+ secData
118
+ } = _ref;
119
+ if (_format.default.isSECLayout(layout) && secData) {
120
+ const {
121
+ d,
122
+ mn,
123
+ mp,
124
+ mw
125
+ } = secData;
126
+ return /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement("div", {
127
+ className: (0, _classnames.default)(classes.rowRoot, classes.rowOdd)
128
+ }, /*#__PURE__*/_react.default.createElement("span", {
129
+ className: (0, _classnames.default)(classes.tTxt, classes.tHead, 'txt-sv-panel-txt')
130
+ }, "Detector: "), /*#__PURE__*/_react.default.createElement("span", {
131
+ className: (0, _classnames.default)(classes.tTxt, 'txt-sv-panel-txt')
132
+ }, detector)), /*#__PURE__*/_react.default.createElement("div", {
133
+ className: (0, _classnames.default)(classes.rowRoot, classes.rowEven)
134
+ }, /*#__PURE__*/_react.default.createElement("span", {
135
+ className: (0, _classnames.default)(classes.tTxt, classes.tHead, 'txt-sv-panel-txt')
136
+ }, "D: "), /*#__PURE__*/_react.default.createElement("span", {
137
+ className: (0, _classnames.default)(classes.tTxt, 'txt-sv-panel-txt')
138
+ }, d)), /*#__PURE__*/_react.default.createElement("div", {
139
+ className: (0, _classnames.default)(classes.rowRoot, classes.rowOdd)
140
+ }, /*#__PURE__*/_react.default.createElement("span", {
141
+ className: (0, _classnames.default)(classes.tTxt, classes.tHead, 'txt-sv-panel-txt')
142
+ }, "MN: "), /*#__PURE__*/_react.default.createElement("span", {
143
+ className: (0, _classnames.default)(classes.tTxt, 'txt-sv-panel-txt')
144
+ }, mn)), /*#__PURE__*/_react.default.createElement("div", {
145
+ className: (0, _classnames.default)(classes.rowRoot, classes.rowEven)
146
+ }, /*#__PURE__*/_react.default.createElement("span", {
147
+ className: (0, _classnames.default)(classes.tTxt, classes.tHead, 'txt-sv-panel-txt')
148
+ }, "MP: "), /*#__PURE__*/_react.default.createElement("span", {
149
+ className: (0, _classnames.default)(classes.tTxt, 'txt-sv-panel-txt')
150
+ }, mp)), /*#__PURE__*/_react.default.createElement("div", {
151
+ className: (0, _classnames.default)(classes.rowRoot, classes.rowOdd)
152
+ }, /*#__PURE__*/_react.default.createElement("span", {
153
+ className: (0, _classnames.default)(classes.tTxt, classes.tHead, 'txt-sv-panel-txt')
154
+ }, "MW: "), /*#__PURE__*/_react.default.createElement("span", {
155
+ className: (0, _classnames.default)(classes.tTxt, 'txt-sv-panel-txt')
156
+ }, mw)));
157
+ }
158
+ return null;
159
+ };
160
+ SECData.propTypes = {
161
+ classes: _propTypes.default.object.isRequired,
162
+ layout: _propTypes.default.string.isRequired,
163
+ detector: _propTypes.default.object.isRequired,
164
+ secData: _propTypes.default.object.isRequired
165
+ };
166
+ const InfoPanel = _ref2 => {
113
167
  let {
114
168
  classes,
115
169
  expand,
@@ -127,12 +181,13 @@ const InfoPanel = _ref => {
127
181
  canChangeDescription,
128
182
  onDescriptionChanged,
129
183
  detectorSt
130
- } = _ref;
184
+ } = _ref2;
131
185
  if (!feature) return null;
132
186
  const {
133
187
  title,
134
188
  observeFrequency,
135
- solventName
189
+ solventName,
190
+ secData
136
191
  } = feature;
137
192
  const {
138
193
  curveIdx
@@ -204,13 +259,12 @@ const InfoPanel = _ref => {
204
259
  className: (0, _classnames.default)(classes.tTxt, classes.tHead, 'txt-sv-panel-txt')
205
260
  }, "Theoretical mass: "), /*#__PURE__*/_react.default.createElement("span", {
206
261
  className: (0, _classnames.default)(classes.tTxt, 'txt-sv-panel-txt')
207
- }, `${parseFloat(theoryMass).toFixed(6)} g/mol`)) : null, _format.default.isSECLayout(layoutSt) ? /*#__PURE__*/_react.default.createElement("div", {
208
- className: (0, _classnames.default)(classes.rowRoot, classes.rowOdd)
209
- }, /*#__PURE__*/_react.default.createElement("span", {
210
- className: (0, _classnames.default)(classes.tTxt, classes.tHead, 'txt-sv-panel-txt')
211
- }, "Detector: "), /*#__PURE__*/_react.default.createElement("span", {
212
- className: (0, _classnames.default)(classes.tTxt, 'txt-sv-panel-txt')
213
- }, selectedDetector)) : null, !molSvg ? null : /*#__PURE__*/_react.default.createElement(_reactSvgFileZoomPan.default, {
262
+ }, `${parseFloat(theoryMass).toFixed(6)} g/mol`)) : null, /*#__PURE__*/_react.default.createElement(SECData, {
263
+ classes: classes,
264
+ layout: layoutSt,
265
+ detector: selectedDetector,
266
+ secData: secData
267
+ }), !molSvg ? null : /*#__PURE__*/_react.default.createElement(_reactSvgFileZoomPan.default, {
214
268
  svg: molSvg,
215
269
  duration: 300,
216
270
  resize: true
@@ -14,7 +14,8 @@ var _list_layout = require("../constants/list_layout");
14
14
  var _integration = require("./integration");
15
15
  /* eslint-disable
16
16
  no-mixed-operators, react/function-component-definition,
17
- prefer-object-spread, camelcase, no-plusplus, prefer-destructuring */
17
+ prefer-object-spread, camelcase, no-plusplus, prefer-destructuring,
18
+ max-len */
18
19
 
19
20
  const getTopic = (_, props) => props.topic;
20
21
  const getFeature = (_, props) => props.feature;
@@ -271,32 +272,6 @@ const Convert2MaxMinPeak = (layout, feature, offset) => {
271
272
  peaks.refIndex = refIndex;
272
273
  return peaks;
273
274
  }
274
-
275
- // // let upperThresVal = upperThres;
276
- // // if (!upperThresVal) {
277
- // // upperThresVal = 1.0;
278
- // // }
279
-
280
- // // let lowerThresVal = lowerThres;
281
- // // if (!lowerThresVal) {
282
- // // lowerThresVal = 1.0;
283
- // // }
284
-
285
- // // const yUpperThres = parseFloat(upperThresVal) / 100.0 * maxY;
286
- // // const yLowerThres = parseFloat(lowerThresVal) / 100.0 * minY;
287
-
288
- // // const corrOffset = offset || 0.0;
289
- // // for (let i = 0; i < data.y.length; i += 1) {
290
- // // const y = data.y[i];
291
- // // const overUpperThres = y >= yUpperThres;
292
- // // const belowThres = y <= yLowerThres;
293
- // // const x = data.x[i] - corrOffset;
294
- // // if (overUpperThres) {
295
- // // peaks.max.push({ x, y });
296
- // // } else if (belowThres) {
297
- // // peaks.min.push({ x, y });
298
- // // }
299
- // // }
300
275
  return peaks;
301
276
  };
302
277
  exports.Convert2MaxMinPeak = Convert2MaxMinPeak;
@@ -773,9 +748,30 @@ const extrFeaturesCylicVolta = (jcamp, layout, peakUp) => {
773
748
  const lowerThres = _format.default.isXRDLayout(layout) ? 100 : calcLowerThres(s);
774
749
  const cpo = buildPeakFeature(jcamp, layout, peakUp, s, 100, upperThres, lowerThres);
775
750
  const bnd = getBoundary(s);
776
- const detector = _format.default.isSECLayout(layout) && jcamp.info.$DETECTOR ? jcamp.info.$DETECTOR : '';
751
+ let detector = '';
752
+ let secData = null;
753
+ if (_format.default.isSECLayout(layout)) {
754
+ const {
755
+ info
756
+ } = jcamp;
757
+ detector = info.$DETECTOR ? info.$DETECTOR : '';
758
+ const {
759
+ D,
760
+ MN,
761
+ MP,
762
+ MW
763
+ } = info;
764
+ secData = {
765
+ d: D,
766
+ mn: MN,
767
+ mp: MP,
768
+ mw: MW
769
+ };
770
+ }
771
+ // const detector = Format.isSECLayout(layout) && jcamp.info.$DETECTOR ? jcamp.info.$DETECTOR : '';
777
772
  return Object.assign({}, base, cpo, bnd, {
778
- detector
773
+ detector,
774
+ secData
779
775
  });
780
776
  }).filter(r => r != null);
781
777
  return features;
@@ -822,7 +818,7 @@ const extractTemperature = jcamp => {
822
818
  const ExtractJcamp = source => {
823
819
  const jcamp = _jcampconverter.default.convert(source, {
824
820
  xy: true,
825
- keepRecordsRegExp: /(\$CSTHRESHOLD|\$CSSCANAUTOTARGET|\$CSSCANEDITTARGET|\$CSSCANCOUNT|\$CSSOLVENTNAME|\$CSSOLVENTVALUE|\$CSSOLVENTX|\$CSCATEGORY|\$CSITAREA|\$CSITFACTOR|\$OBSERVEDINTEGRALS|\$OBSERVEDMULTIPLETS|\$OBSERVEDMULTIPLETSPEAKS|\.SOLVENTNAME|\.OBSERVEFREQUENCY|\$CSSIMULATIONPEAKS|\$CSUPPERTHRESHOLD|\$CSLOWERTHRESHOLD|\$CSCYCLICVOLTAMMETRYDATA|UNITS|SYMBOL|CSAUTOMETADATA|\$DETECTOR)/ // eslint-disable-line
821
+ keepRecordsRegExp: /(\$CSTHRESHOLD|\$CSSCANAUTOTARGET|\$CSSCANEDITTARGET|\$CSSCANCOUNT|\$CSSOLVENTNAME|\$CSSOLVENTVALUE|\$CSSOLVENTX|\$CSCATEGORY|\$CSITAREA|\$CSITFACTOR|\$OBSERVEDINTEGRALS|\$OBSERVEDMULTIPLETS|\$OBSERVEDMULTIPLETSPEAKS|\.SOLVENTNAME|\.OBSERVEFREQUENCY|\$CSSIMULATIONPEAKS|\$CSUPPERTHRESHOLD|\$CSLOWERTHRESHOLD|\$CSCYCLICVOLTAMMETRYDATA|UNITS|SYMBOL|CSAUTOMETADATA|\$DETECTOR|MN|MW|D|MP)/ // eslint-disable-line
826
822
  });
827
823
  const layout = readLayout(jcamp);
828
824
  const peakUp = !_format.default.isIrLayout(layout);
@@ -910,11 +906,12 @@ const GetCyclicVoltaPreviousShift = (cyclicVolta, curveIdx) => {
910
906
  return 0.0;
911
907
  }
912
908
  const {
913
- shift
909
+ shift,
910
+ hasRefPeak
914
911
  } = spectraList[curveIdx];
915
912
  const {
916
913
  prevValue
917
914
  } = shift;
918
- return prevValue;
915
+ return hasRefPeak ? prevValue : -prevValue;
919
916
  };
920
917
  exports.GetCyclicVoltaPreviousShift = GetCyclicVoltaPreviousShift;
@@ -8,18 +8,40 @@ var _action_type = require("../constants/action_type");
8
8
  /* eslint-disable default-param-last, prefer-object-spread */
9
9
 
10
10
  const initialState = {
11
- xUnit: '',
12
- yUnit: ''
11
+ axes: [{
12
+ xUnit: '',
13
+ yUnit: ''
14
+ }]
13
15
  };
14
16
  const updateAxis = function (state, payload) {
15
17
  let isYAxis = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
18
+ const {
19
+ value,
20
+ curveIndex
21
+ } = payload;
22
+ const {
23
+ axes
24
+ } = state;
25
+ let selectedAxes = axes[curveIndex];
26
+ if (!selectedAxes) {
27
+ selectedAxes = {
28
+ xUnit: '',
29
+ yUnit: ''
30
+ };
31
+ }
32
+ let newAxes = null;
16
33
  if (isYAxis) {
17
- return Object.assign({}, state, {
18
- yUnit: payload
34
+ newAxes = Object.assign({}, selectedAxes, {
35
+ yUnit: value
36
+ });
37
+ } else {
38
+ newAxes = Object.assign({}, selectedAxes, {
39
+ xUnit: value
19
40
  });
20
41
  }
42
+ axes[curveIndex] = newAxes;
21
43
  return Object.assign({}, state, {
22
- xUnit: payload
44
+ axes
23
45
  });
24
46
  };
25
47
  const axesReducer = function () {
@@ -13,6 +13,7 @@ const initialState = {
13
13
  };
14
14
  const initSpectra = {
15
15
  list: [],
16
+ origin: [],
16
17
  selectedIdx: -1,
17
18
  isWorkMaxPeak: true,
18
19
  jcampIdx: -1,
@@ -20,7 +21,9 @@ const initSpectra = {
20
21
  ref: null,
21
22
  val: 0,
22
23
  prevValue: 0
23
- }
24
+ },
25
+ hasRefPeak: false,
26
+ history: []
24
27
  };
25
28
  const addPairPeak = (state, action) => {
26
29
  const {
@@ -51,12 +54,14 @@ const addPairPeak = (state, action) => {
51
54
  min: null,
52
55
  max: null,
53
56
  isRef: false,
54
- e12: null
57
+ e12: null,
58
+ createdAt: Date.now()
55
59
  });
56
60
  spectraList[payload] = Object.assign({}, spectra, {
57
61
  list: newList,
58
- selectedIdx: index
59
- });
62
+ selectedIdx: index,
63
+ origin: [...newList]
64
+ }); // eslint-disable-line
60
65
  return Object.assign({}, state, {
61
66
  spectraList
62
67
  });
@@ -78,12 +83,15 @@ const removePairPeak = (state, action) => {
78
83
  const spectra = spectraList[jcampIdx];
79
84
  if (spectra) {
80
85
  const {
81
- list
86
+ list,
87
+ origin
82
88
  } = spectra;
83
89
  list.splice(index, 1);
90
+ origin.splice(index, 1);
84
91
  spectraList[jcampIdx] = Object.assign({}, spectra, {
85
92
  list,
86
- selectedIdx: index
93
+ selectedIdx: index,
94
+ origin
87
95
  });
88
96
  return Object.assign({}, state, {
89
97
  spectraList
@@ -139,11 +147,13 @@ const addPeak = function (state, action) {
139
147
  });
140
148
  }
141
149
  pairPeak.e12 = getE12(pairPeak);
150
+ pairPeak.updatedAt = Date.now();
142
151
  newList[index] = pairPeak;
143
152
  spectraList[jcampIdx] = Object.assign({}, spectra, {
144
153
  list: newList,
145
154
  selectedIdx: index,
146
- jcampIdx
155
+ jcampIdx,
156
+ origin: [...newList]
147
157
  });
148
158
  return Object.assign({}, state, {
149
159
  spectraList
@@ -176,11 +186,13 @@ const removePeak = function (state, action) {
176
186
  pairPeak.min = null;
177
187
  }
178
188
  pairPeak.e12 = getE12(pairPeak);
189
+ pairPeak.updatedAt = Date.now();
179
190
  newList[index] = pairPeak;
180
191
  spectraList[jcampIdx] = Object.assign({}, spectra, {
181
192
  list: newList,
182
193
  selectedIdx: index,
183
- jcampIdx
194
+ jcampIdx,
195
+ origin: [...newList]
184
196
  });
185
197
  return Object.assign({}, state, {
186
198
  spectraList
@@ -258,11 +270,13 @@ const addPecker = (state, action) => {
258
270
  const newList = list;
259
271
  const pairPeak = newList[index];
260
272
  pairPeak.pecker = peak;
273
+ pairPeak.updatedAt = Date.now();
261
274
  newList[index] = pairPeak;
262
275
  spectraList[jcampIdx] = Object.assign({}, spectra, {
263
276
  list: newList,
264
277
  selectedIdx: index,
265
- jcampIdx
278
+ jcampIdx,
279
+ origin: [...newList]
266
280
  });
267
281
  return Object.assign({}, state, {
268
282
  spectraList
@@ -289,11 +303,13 @@ const removePecker = (state, action) => {
289
303
  const newList = list;
290
304
  const pairPeak = newList[index];
291
305
  pairPeak.pecker = null;
306
+ pairPeak.updatedAt = Date.now();
292
307
  newList[index] = pairPeak;
293
308
  spectraList[jcampIdx] = Object.assign({}, spectra, {
294
309
  list: newList,
295
310
  selectedIdx: index,
296
- jcampIdx
311
+ jcampIdx,
312
+ origin: [...newList]
297
313
  });
298
314
  return Object.assign({}, state, {
299
315
  spectraList
@@ -315,12 +331,14 @@ const setRef = (state, action) => {
315
331
  const spectra = spectraList[jcampIdx];
316
332
  const {
317
333
  list,
318
- shift
334
+ shift,
335
+ hasRefPeak,
336
+ history
319
337
  } = spectra;
320
338
  const newShift = Object.assign({}, shift);
321
339
  const refPeaks = list.filter(pairPeak => pairPeak.isRef === true);
322
340
  let offset = 0.0;
323
- if (refPeaks.length > 0) {
341
+ if (hasRefPeak) {
324
342
  const currRefPeaks = refPeaks[0];
325
343
  newShift.ref = currRefPeaks;
326
344
  const {
@@ -330,51 +348,107 @@ const setRef = (state, action) => {
330
348
  e12
331
349
  } = currRefPeaks;
332
350
  offset = e12 - val;
351
+ const newList = spectra.list.map(pairPeak => {
352
+ //eslint-disable-line
353
+ const {
354
+ max,
355
+ min,
356
+ pecker,
357
+ isRef
358
+ } = pairPeak;
359
+ let newMax = null;
360
+ let newMin = null;
361
+ let newPecker = null;
362
+ if (max) {
363
+ newMax = hasRefPeak ? {
364
+ x: max.x - offset,
365
+ y: max.y
366
+ } : {
367
+ x: max.x + parseFloat(offset),
368
+ y: max.y
369
+ };
370
+ }
371
+ if (min) {
372
+ newMin = hasRefPeak ? {
373
+ x: min.x - offset,
374
+ y: min.y
375
+ } : {
376
+ x: min.x + parseFloat(offset),
377
+ y: min.y
378
+ };
379
+ }
380
+ if (pecker) {
381
+ newPecker = hasRefPeak ? {
382
+ x: pecker.x - offset,
383
+ y: pecker.y
384
+ } : {
385
+ x: pecker.x + parseFloat(offset),
386
+ y: pecker.y
387
+ }; //eslint-disable-line
388
+ }
389
+ const newPairPeak = Object.assign({}, pairPeak, {
390
+ max: newMax,
391
+ min: newMin,
392
+ pecker: newPecker
393
+ }); //eslint-disable-line
394
+ newPairPeak.e12 = getE12(newPairPeak);
395
+ newPairPeak.updatedAt = Date.now();
396
+ if (isRef) {
397
+ newShift.ref = newPairPeak;
398
+ newShift.prevValue += offset;
399
+ }
400
+ return newPairPeak;
401
+ });
402
+ history.push(...[newList]);
403
+ spectra.list = newList;
333
404
  } else {
334
405
  newShift.ref = null;
335
- }
336
- const newList = spectra.list.map(pairPeak => {
337
- //eslint-disable-line
338
406
  const {
339
- max,
340
- min,
341
- pecker,
342
- isRef
343
- } = pairPeak;
344
- let newMax = null;
345
- let newMin = null;
346
- let newPecker = null;
347
- if (max) {
348
- newMax = {
349
- x: max.x - offset,
350
- y: max.y
351
- };
352
- }
353
- if (min) {
354
- newMin = {
355
- x: min.x - offset,
356
- y: min.y
357
- };
358
- }
359
- if (pecker) {
360
- newPecker = {
361
- x: pecker.x - offset,
362
- y: pecker.y
363
- };
364
- }
365
- const newPairPeak = Object.assign({}, pairPeak, {
366
- max: newMax,
367
- min: newMin,
368
- pecker: newPecker
369
- }); //eslint-disable-line
370
- newPairPeak.e12 = getE12(newPairPeak);
371
- if (isRef) {
372
- newShift.ref = newPairPeak;
373
- newShift.prevValue += offset;
374
- }
375
- return newPairPeak;
376
- });
377
- spectra.list = newList;
407
+ val
408
+ } = newShift;
409
+ offset = val;
410
+ const newList = spectra.origin.map(pairPeak => {
411
+ //eslint-disable-line
412
+ const {
413
+ max,
414
+ min,
415
+ pecker
416
+ } = pairPeak;
417
+ let newMax = null;
418
+ let newMin = null;
419
+ let newPecker = null;
420
+ if (max) {
421
+ newMax = {
422
+ x: max.x + parseFloat(val),
423
+ y: max.y
424
+ };
425
+ }
426
+ if (min) {
427
+ newMin = {
428
+ x: min.x + parseFloat(val),
429
+ y: min.y
430
+ };
431
+ }
432
+ if (pecker) {
433
+ newPecker = {
434
+ x: pecker.x + parseFloat(val),
435
+ y: pecker.y
436
+ };
437
+ }
438
+ const newPairPeak = Object.assign({}, pairPeak, {
439
+ max: newMax,
440
+ min: newMin,
441
+ pecker: newPecker,
442
+ isRef: false
443
+ }); //eslint-disable-line
444
+ newPairPeak.e12 = getE12(newPairPeak);
445
+ newPairPeak.updatedAt = Date.now();
446
+ return newPairPeak;
447
+ });
448
+ history.push(...[newList]);
449
+ spectra.list = newList;
450
+ newShift.prevValue = parseFloat(offset);
451
+ }
378
452
  spectraList[jcampIdx] = Object.assign({}, spectra, {
379
453
  shift: newShift,
380
454
  jcampIdx
@@ -400,21 +474,30 @@ const selectRefPeaks = (state, action) => {
400
474
  } = payload;
401
475
  const spectra = spectraList[jcampIdx];
402
476
  const {
403
- list
477
+ list,
478
+ shift,
479
+ history
404
480
  } = spectra;
481
+ const newShift = shift;
405
482
  const newList = list;
406
483
  newList.forEach((pairPeak, idx) => {
407
484
  const newPairPeak = pairPeak;
408
485
  newPairPeak.isRef = false;
486
+ newPairPeak.updatedAt = Date.now();
409
487
  if (idx === index) {
410
488
  newPairPeak.isRef = checked;
411
489
  newList[index] = newPairPeak;
412
490
  }
413
491
  });
492
+ const refPeaks = newList.filter(pairPeak => pairPeak.isRef === true);
493
+ const hasRefPeak = refPeaks.length > 0;
494
+ history.push(...[newList]);
414
495
  spectraList[jcampIdx] = Object.assign({}, spectra, {
415
496
  list: newList,
416
497
  selectedIdx: index,
417
- jcampIdx
498
+ jcampIdx,
499
+ hasRefPeak,
500
+ shift: newShift
418
501
  });
419
502
  return Object.assign({}, state, {
420
503
  spectraList
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@complat/react-spectra-editor",
3
- "version": "1.2.1",
3
+ "version": "1.3.1",
4
4
  "description": "An editor to View and Edit Chemical Spectra data (NMR, IR and MS, CV, UIVIS, XRD).",
5
5
  "repository": {
6
6
  "type": "git",
@@ -8,7 +8,7 @@
8
8
  },
9
9
  "license": "AGPL-3.0",
10
10
  "dependencies": {
11
- "@complat/react-svg-file-zoom-pan": "1.1.3",
11
+ "@complat/react-svg-file-zoom-pan": "1.1.4",
12
12
  "@emotion/react": "^11.11.1",
13
13
  "@emotion/styled": "^11.11.0",
14
14
  "@mdi/js": "^7.2.96",