From 52e5085dd0320bfbbe79f629d3fd48656e6427c0 Mon Sep 17 00:00:00 2001 From: Nicolass67 Date: Tue, 27 Jan 2026 10:36:27 +0100 Subject: [PATCH 1/4] Limit multi spectra mode to 2+ items --- src/layer_init.js | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/src/layer_init.js b/src/layer_init.js index 132877b9..0c6d57da 100644 --- a/src/layer_init.js +++ b/src/layer_init.js @@ -98,8 +98,22 @@ class LayerInit extends React.Component { } updateMultiEntities() { - const { multiEntities, setAllCurvesAct } = this.props; - setAllCurvesAct(multiEntities); + const { multiEntities, setAllCurvesAct, entity } = this.props; + const isMultiSpectra = Array.isArray(multiEntities) && multiEntities.length > 1; + if (isMultiSpectra) { + setAllCurvesAct(multiEntities); + return; + } + + if (Format.isCyclicVoltaLayout(entity.layout)) { + const payload = (Array.isArray(multiEntities) && multiEntities.length > 0) + ? multiEntities + : [entity]; + setAllCurvesAct(payload); + return; + } + + setAllCurvesAct(false); } render() { @@ -116,7 +130,8 @@ class LayerInit extends React.Component { const xxLabel = !xLabel && xLabel === '' ? `X (${target.xUnit})` : xLabel; const yyLabel = !yLabel && yLabel === '' ? `Y (${target.yUnit})` : yLabel; - if (multiEntities) { + const isMultiSpectra = Array.isArray(multiEntities) && multiEntities.length > 1; + if (isMultiSpectra) { return ( Date: Wed, 28 Jan 2026 11:08:14 +0100 Subject: [PATCH 2/4] Fix multi spectra predict flow --- src/__tests__/fixtures/nmr13c_dept_jcamp.js | 22 +++++ src/__tests__/fixtures/nmr1h_2_jcamp.js | 11 +++ src/__tests__/fixtures/nmr_result_alt.js | 71 +++++++++++++++ .../units/reducers/reducer_forecast.test.tsx | 22 +++-- src/components/cmd_bar/01_viewer.js | 10 ++- src/components/cmd_bar/r04_submit.js | 15 +++- src/components/cmd_bar/r05_submit_btn.js | 15 +++- src/components/cmd_bar/r06_predict_btn.js | 20 ++++- src/components/d3_line/index.js | 4 +- src/components/forecast/ir_comps.js | 8 +- src/components/forecast/ir_viewer.js | 46 ++++++---- src/components/forecast/nmr_comps.js | 8 +- src/components/forecast/nmr_viewer.js | 48 ++++++---- src/components/forecast_viewer.js | 17 +++- src/components/multi_jcamps_viewer.js | 51 ++++++++--- src/index.js | 14 +-- src/layer_init.js | 25 +++++- src/reducers/reducer_curve.js | 12 ++- src/reducers/reducer_forecast.js | 90 ++++++++++++++----- src/sagas/saga_multi_entities.js | 26 ++++++ 20 files changed, 440 insertions(+), 95 deletions(-) create mode 100644 src/__tests__/fixtures/nmr_result_alt.js diff --git a/src/__tests__/fixtures/nmr13c_dept_jcamp.js b/src/__tests__/fixtures/nmr13c_dept_jcamp.js index 30204ba8..77b767f4 100644 --- a/src/__tests__/fixtures/nmr13c_dept_jcamp.js +++ b/src/__tests__/fixtures/nmr13c_dept_jcamp.js @@ -3281,6 +3281,28 @@ $$ === CHEMSPECTRA === ##$OBSERVEDMULTIPLETS= ##$OBSERVEDMULTIPLETSPEAKS= +$$ === CHEMSPECTRA SIMULATION === +##$CSSIMULATIONPEAKS= +10.123456 +11.123456 +12.123456 +13.123456 +14.123456 +15.123456 +16.123456 +17.123456 +18.123456 +19.123456 +20.123456 +21.123456 +28.550000190734863 +28.59999942779541 +33.29999923706055 +107.20000076293945 +143.5500030517578 +147.8000030517578 +151.35000610351562 +154.8499984741211 ##END= diff --git a/src/__tests__/fixtures/nmr1h_2_jcamp.js b/src/__tests__/fixtures/nmr1h_2_jcamp.js index 4d9cc5a1..31c8f5f3 100644 --- a/src/__tests__/fixtures/nmr1h_2_jcamp.js +++ b/src/__tests__/fixtures/nmr1h_2_jcamp.js @@ -2518,6 +2518,17 @@ $$ === CHEMSPECTRA INTEGRALS AND MULTIPLETS === (1, 1.845019816906854, 288947400) $$ === CHEMSPECTRA SIMULATION === ##$CSSIMULATIONPEAKS= +1.10 +1.25 +1.50 +2.75 +3.10 +3.10 +5.50 +7.25 +7.25 +9.00 +9.45 ##END= diff --git a/src/__tests__/fixtures/nmr_result_alt.js b/src/__tests__/fixtures/nmr_result_alt.js new file mode 100644 index 00000000..1988f4e2 --- /dev/null +++ b/src/__tests__/fixtures/nmr_result_alt.js @@ -0,0 +1,71 @@ +/* eslint-disable */ +import nmrSvg from './nmr_svg'; + +const nmrResultAlt = { + outline: { + code: 200, + text: 'Alt load from files.', + }, + output: { + result: [ + { + id: 2, + type: 'nmr;13C;1d', + svgs: [nmrSvg], + statistics: { + accept: 2, + warning: 1, + reject: 2, + missing: 1, + total: 6, + }, + shifts: [ + { + atom: 1, + prediction: 128.4000015258789, + real: 116.0, + diff: 12.400001525878906, + status: 'warning', + }, + { + atom: 2, + prediction: 118.80000305175781, + real: 104.5, + diff: 14.300003051757812, + status: 'reject', + }, + { + atom: 3, + prediction: 140.7500000000000, + real: 124.2, + diff: 16.55, + status: 'accept', + }, + { + atom: 4, + prediction: 151.2500000000000, + real: 139.0, + diff: 12.25, + status: 'accept', + }, + { + atom: 5, + prediction: 134.1999969482422, + real: 120.0, + diff: 14.199996948242188, + status: 'reject', + }, + { + atom: 6, + prediction: 147.13500213623047, + real: 0.0, + diff: 0.0, + status: 'missing', + }, + ], + }, + ], + }, +}; + +export default nmrResultAlt; diff --git a/src/__tests__/units/reducers/reducer_forecast.test.tsx b/src/__tests__/units/reducers/reducer_forecast.test.tsx index 8ba1d97c..c2457216 100644 --- a/src/__tests__/units/reducers/reducer_forecast.test.tsx +++ b/src/__tests__/units/reducers/reducer_forecast.test.tsx @@ -9,6 +9,7 @@ describe('Test redux reducer for forecast', () => { interface ForecastState { predictions: ForecastPrediction + predictionsByCurve: Record } interface ForcastAction { @@ -21,8 +22,8 @@ describe('Test redux reducer for forecast', () => { let initState: ForecastState beforeEach(() => { - forecastState = { predictions: { outline: {}, output: { result: [] }, } } - initState = { predictions: { outline: {}, output: { result: [] }, } } + forecastState = { predictions: { outline: {}, output: { result: [] }, }, predictionsByCurve: {} } + initState = { predictions: { outline: {}, output: { result: [] }, }, predictionsByCurve: {} } action = { type: "", payload: null } }) @@ -41,16 +42,25 @@ describe('Test redux reducer for forecast', () => { }) it('Init with payload', () => { - const payload: ForecastPrediction = { outline: {}, output: {} } + const payload: any = { + predictions: { outline: {}, output: {} }, + curveIdx: 1, + } action.payload = payload const newState = forecastReducer(forecastState, action) - expect(newState).toEqual(payload) + expect(newState).toEqual({ + ...forecastState, + predictions: payload.predictions, + predictionsByCurve: { + 1: payload.predictions, + }, + }) }) }) describe('Clear and reset', () => { beforeEach(() => { - forecastState = { predictions: { outline: null, output: null }} + forecastState = { predictions: { outline: null, output: null }, predictionsByCurve: {} } }) it('Clear status', () => { @@ -63,7 +73,7 @@ describe('Test redux reducer for forecast', () => { it('Reset status', () => { action.type = MANAGER.RESETALL const newState = forecastReducer(forecastState, action) - expect(newState).toEqual(initState) + expect(newState).toEqual(forecastState) }) }) diff --git a/src/components/cmd_bar/01_viewer.js b/src/components/cmd_bar/01_viewer.js index d1dff1a2..b37f7ed4 100644 --- a/src/components/cmd_bar/01_viewer.js +++ b/src/components/cmd_bar/01_viewer.js @@ -12,6 +12,7 @@ import Tooltip from '@mui/material/Tooltip'; import { setUiViewerType } from '../../actions/ui'; import Cfg from '../../helpers/cfg'; +import Format from '../../helpers/format'; import { MuButton, commonStyle, focusStyle } from './common'; import { LIST_UI_VIEWER_TYPE } from '../../constants/list_ui'; @@ -73,7 +74,14 @@ const mapStateToProps = (state, props) => ( // eslint-disable-line { isfocusSpectrumSt: state.ui.viewer === LIST_UI_VIEWER_TYPE.SPECTRUM, isfocusAnalysisSt: state.ui.viewer === LIST_UI_VIEWER_TYPE.ANALYSIS, - hideCmdAnaViewerSt: Cfg.hideCmdAnaViewer(state.layout) || props.editorOnly, + hideCmdAnaViewerSt: Cfg.hideCmdAnaViewer(state.layout) + || ( + props.editorOnly + && !( + Format.isNmrLayout(state.layout) + || Format.isIrLayout(state.layout) + ) + ), disableCmdAnaViewerSt: Cfg.btnCmdAnaViewer(state.layout), } ); diff --git a/src/components/cmd_bar/r04_submit.js b/src/components/cmd_bar/r04_submit.js index f7acdf37..6215e8e8 100644 --- a/src/components/cmd_bar/r04_submit.js +++ b/src/components/cmd_bar/r04_submit.js @@ -212,7 +212,7 @@ const selectOperation = (name, operations, updateOperationAct) => { const Submit = ({ operations, classes, feature, forecast, editorOnly, hideSwitch, disabled, - isAscendSt, isIntensitySt, operationSt, decimalSt, isEmWaveSt, + isAscendSt, isIntensitySt, operationSt, decimalSt, isEmWaveSt, layoutSt, toggleIsAscendAct, toggleIsIntensityAct, updateOperationAct, updateDecimalAct, }) => { @@ -222,6 +222,11 @@ const Submit = ({ if (!operations || operations.length === 0) return null; + const allowPredictInEditorOnly = Format.is1HLayout(layoutSt) + || Format.is13CLayout(layoutSt) + || Format.isIrLayout(layoutSt); + const shouldShowPredict = !editorOnly || allowPredictInEditorOnly; + return ( { @@ -240,14 +245,14 @@ const Submit = ({ ) } { - editorOnly - ? null - : ( + shouldShowPredict + ? ( ) + : null } { operationSelect( @@ -267,6 +272,7 @@ const Submit = ({ const mapStateToProps = (state, props) => ( // eslint-disable-line { + layoutSt: state.layout, isEmWaveSt: Format.isEmWaveLayout(state.layout), isAscendSt: state.submit.isAscend, isIntensitySt: state.submit.isIntensity, @@ -293,6 +299,7 @@ Submit.propTypes = { operationSt: PropTypes.object.isRequired, hideSwitch: PropTypes.bool.isRequired, disabled: PropTypes.bool.isRequired, + layoutSt: PropTypes.string.isRequired, isAscendSt: PropTypes.bool.isRequired, isIntensitySt: PropTypes.bool.isRequired, isEmWaveSt: PropTypes.bool.isRequired, diff --git a/src/components/cmd_bar/r05_submit_btn.js b/src/components/cmd_bar/r05_submit_btn.js index c1c21491..d8685727 100644 --- a/src/components/cmd_bar/r05_submit_btn.js +++ b/src/components/cmd_bar/r05_submit_btn.js @@ -68,6 +68,19 @@ const BtnSubmit = ({ const thres = Convert2Thres(feature, thresSt); const aucValues = extractAreaUnderCurve(allIntegrationSt, integrationSt, layoutSt); const { dscMetaData } = metaSt; + const predictionsByCurve = forecastSt.predictionsByCurve || {}; + const hasCurvePredictions = Object.prototype.hasOwnProperty.call( + predictionsByCurve, + curveSt.curveIdx, + ); + const hasAnyCurvePredictions = Object.keys(predictionsByCurve).length > 0; + const emptyPredictions = { outline: {}, output: { result: [] } }; + let activePredictions = forecastSt.predictions; + if (hasCurvePredictions) { + activePredictions = predictionsByCurve[curveSt.curveIdx]; + } else if (hasAnyCurvePredictions) { + activePredictions = emptyPredictions; + } if (!operation) return null; @@ -82,7 +95,7 @@ const BtnSubmit = ({ color="primary" onClick={onClickCb( operation.value, peaksEdit, isAscend, isIntensity, - scan, thres, layoutSt, shiftSt, forecastSt.predictions, decimalSt, + scan, thres, layoutSt, shiftSt, activePredictions, decimalSt, integrationSt, multiplicitySt, allIntegrationSt, aucValues, waveLengthSt, cyclicvoltaSt, curveSt, axesUnitsSt, detectorSt, dscMetaData, )} diff --git a/src/components/cmd_bar/r06_predict_btn.js b/src/components/cmd_bar/r06_predict_btn.js index 18d4e3a1..7f6988fa 100644 --- a/src/components/cmd_bar/r06_predict_btn.js +++ b/src/components/cmd_bar/r06_predict_btn.js @@ -199,7 +199,7 @@ const renderBtnUnknown = ( const BtnPredict = ({ classes, feature, forecast, layoutSt, simulationSt, editPeakSt, scanSt, shiftSt, thresSt, - integrationSt, multiplicitySt, + integrationSt, multiplicitySt, forecastSt, setUiViewerTypeAct, curveSt, }) => { const is13Cor1H = Format.is13CLayout(layoutSt) || Format.is1HLayout(layoutSt); @@ -212,11 +212,21 @@ const BtnPredict = ({ const thres = Convert2Thres(feature, thresSt); const simuCount = simulationSt.nmrSimPeaks.length; const uniqCount = [...new Set(simulationSt.nmrSimPeaks)].length; + const { curveIdx } = curveSt; + const predictionsByCurve = (forecastSt && forecastSt.predictionsByCurve) || {}; + const hasCurvePredictions = Object.prototype.hasOwnProperty.call(predictionsByCurve, curveIdx); + const hasAnyCurvePredictions = Object.keys(predictionsByCurve).length > 0; + const emptyPredictions = { outline: {}, output: { result: [] } }; + let analysisPredictions = (forecastSt && forecastSt.predictions) || forecast.predictions; + if (hasCurvePredictions) { + analysisPredictions = predictionsByCurve[curveIdx]; + } else if (hasAnyCurvePredictions) { + analysisPredictions = emptyPredictions; + } let realCount = 0; if (Format.is13CLayout(layoutSt)) { realCount = carbonFeatures(peaksEdit, multiplicitySt).length; } else { - const { curveIdx } = curveSt; const { multiplicities } = multiplicitySt; const selectedMultiplicity = multiplicities[curveIdx]; const { stack } = selectedMultiplicity; @@ -226,7 +236,7 @@ const BtnPredict = ({ if (is13Cor1H && simuCount === 0) { const onClickUnknownCb = onClicUnknown( feature, forecast, peaksEdit, layoutSt, scan, shiftSt, thres, - forecast.predictions, integrationSt, multiplicitySt, curveSt, + analysisPredictions, integrationSt, multiplicitySt, curveSt, ); return renderBtnUnknown(classes, onClickUnknownCb); } @@ -238,7 +248,7 @@ const BtnPredict = ({ ? ( onClickReady( forecast, peaksEdit, layoutSt, scan, shiftSt, thres, - forecast.predictions, integrationSt, multiplicitySt, setUiViewerTypeAct, curveSt, + analysisPredictions, integrationSt, multiplicitySt, setUiViewerTypeAct, curveSt, ) ) : onClickFail(layoutSt, simuCount, realCount); @@ -263,6 +273,7 @@ const mapStateToProps = (state, props) => ( // eslint-disable-line integrationSt: state.integration.present, multiplicitySt: state.multiplicity.present, curveSt: state.curve, + forecastSt: state.forecast, } ); @@ -284,6 +295,7 @@ BtnPredict.propTypes = { thresSt: PropTypes.object.isRequired, integrationSt: PropTypes.object.isRequired, multiplicitySt: PropTypes.object.isRequired, + forecastSt: PropTypes.object.isRequired, setUiViewerTypeAct: PropTypes.func.isRequired, curveSt: PropTypes.object, }; diff --git a/src/components/d3_line/index.js b/src/components/d3_line/index.js index d42c2796..f8fdfbc2 100644 --- a/src/components/d3_line/index.js +++ b/src/components/d3_line/index.js @@ -42,7 +42,9 @@ class ViewerLine extends React.Component { resetAllAct, } = this.props; drawDestroy(this.rootKlass); - resetAllAct(feature); + if (!isHidden) { + resetAllAct(feature); + } let xxLabel = xLabel; let yyLabel = yLabel; diff --git a/src/components/forecast/ir_comps.js b/src/components/forecast/ir_comps.js index 1920cdca..c750d21d 100644 --- a/src/components/forecast/ir_comps.js +++ b/src/components/forecast/ir_comps.js @@ -20,7 +20,7 @@ import { setIrStatus } from '../../actions/forecast'; // import SmaToSvg from '../common/chem'; const baseSelectIrStatus = ({ - sma, status, identity, + sma, status, identity, curveIdx, setIrStatusAct, }) => { const theStatus = ['accept', 'reject'].includes(status) ? status : ''; @@ -35,6 +35,7 @@ const baseSelectIrStatus = ({ sma, identity, value: e.target.value, }, svgs: [], + curveIdx, }); }} > @@ -53,7 +54,9 @@ const baseSelectIrStatus = ({ }; const bssMapStateToProps = (state, props) => ( // eslint-disable-line - {} + { + curveIdx: state.curve.curveIdx, + } ); const bssMapDispatchToProps = (dispatch) => ( @@ -66,6 +69,7 @@ baseSelectIrStatus.propTypes = { sma: PropTypes.string.isRequired, status: PropTypes.string, identity: PropTypes.string.isRequired, + curveIdx: PropTypes.number.isRequired, setIrStatusAct: PropTypes.func.isRequired, }; diff --git a/src/components/forecast/ir_viewer.js b/src/components/forecast/ir_viewer.js index 8c053caf..e8f8cf8f 100644 --- a/src/components/forecast/ir_viewer.js +++ b/src/components/forecast/ir_viewer.js @@ -81,26 +81,41 @@ const sectionTable = (classes, pds) => { }; const IrViewer = ({ // eslint-disable-line - classes, molecule, inputCb, forecastSt, -}) => ( -
- - - - { sectionSvg(classes, forecastSt.predictions) } - - - - { sectionTable(classes, forecastSt.predictions) } + classes, molecule, inputCb, forecastSt, curveSt, +}) => { + const { curveIdx } = curveSt; + const predictionsByCurve = forecastSt.predictionsByCurve || {}; + const hasCurvePredictions = Object.prototype.hasOwnProperty.call(predictionsByCurve, curveIdx); + const hasAnyCurvePredictions = Object.keys(predictionsByCurve).length > 0; + const emptyPredictions = { outline: {}, output: { result: [] } }; + let activePredictions = forecastSt.predictions; + if (hasCurvePredictions) { + activePredictions = predictionsByCurve[curveIdx]; + } else if (hasAnyCurvePredictions) { + activePredictions = emptyPredictions; + } + + return ( +
+ + + + { sectionSvg(classes, activePredictions) } + + + + { sectionTable(classes, activePredictions) } + - - { sectionInput(classes, molecule, inputCb) } -
-); + { sectionInput(classes, molecule, inputCb) } +
+ ); +}; const mapStateToProps = (state, props) => ( // eslint-disable-line { forecastSt: state.forecast, + curveSt: state.curve, } ); @@ -117,6 +132,7 @@ IrViewer.propTypes = { PropTypes.bool, ]), forecastSt: PropTypes.object.isRequired, + curveSt: PropTypes.object.isRequired, }; IrViewer.defaultProps = { diff --git a/src/components/forecast/nmr_comps.js b/src/components/forecast/nmr_comps.js index e7ef121f..a464c847 100644 --- a/src/components/forecast/nmr_comps.js +++ b/src/components/forecast/nmr_comps.js @@ -18,7 +18,7 @@ import { import { setNmrStatus } from '../../actions/forecast'; const baseSelectNmrStatus = ({ // eslint-disable-line - idx, atom, status, identity, + idx, atom, status, identity, curveIdx, setNmrStatusAct, }) => { const theStatus = ['accept', 'reject'].includes(status) ? status : ''; @@ -33,6 +33,7 @@ const baseSelectNmrStatus = ({ // eslint-disable-line idx, atom, identity, value: e.target.value, }, svgs: [], + curveIdx, }); }} > @@ -51,7 +52,9 @@ const baseSelectNmrStatus = ({ // eslint-disable-line }; const bssMapStateToProps = (state, props) => ( // eslint-disable-line - {} + { + curveIdx: state.curve.curveIdx, + } ); const bssMapDispatchToProps = (dispatch) => ( @@ -65,6 +68,7 @@ baseSelectNmrStatus.propTypes = { atom: PropTypes.number.isRequired, status: PropTypes.string, identity: PropTypes.string.isRequired, + curveIdx: PropTypes.number.isRequired, setNmrStatusAct: PropTypes.func.isRequired, }; diff --git a/src/components/forecast/nmr_viewer.js b/src/components/forecast/nmr_viewer.js index 76371af5..ba6f7366 100644 --- a/src/components/forecast/nmr_viewer.js +++ b/src/components/forecast/nmr_viewer.js @@ -81,27 +81,42 @@ const sectionTable = (classes, pds) => { }; const NmrViewer = ({ // eslint-disable-line - classes, molecule, inputCb, forecastSt, -}) => ( -
- - - - { sectionSvg(classes, forecastSt.predictions) } - - - - { sectionTable(classes, forecastSt.predictions) } + classes, molecule, inputCb, forecastSt, curveSt, +}) => { + const { curveIdx } = curveSt; + const predictionsByCurve = forecastSt.predictionsByCurve || {}; + const hasCurvePredictions = Object.prototype.hasOwnProperty.call(predictionsByCurve, curveIdx); + const hasAnyCurvePredictions = Object.keys(predictionsByCurve).length > 0; + const emptyPredictions = { outline: {}, output: { result: [] } }; + let activePredictions = forecastSt.predictions; + if (hasCurvePredictions) { + activePredictions = predictionsByCurve[curveIdx]; + } else if (hasAnyCurvePredictions) { + activePredictions = emptyPredictions; + } + + return ( +
+ + + + { sectionSvg(classes, activePredictions) } + + + + { sectionTable(classes, activePredictions) } + - - { sectionInput(classes, molecule, inputCb) } - { SectionReference(classes) } -
-); + { sectionInput(classes, molecule, inputCb) } + { SectionReference(classes) } +
+ ); +}; const mapStateToProps = (state, props) => ( // eslint-disable-line { forecastSt: state.forecast, + curveSt: state.curve, } ); @@ -118,6 +133,7 @@ NmrViewer.propTypes = { PropTypes.bool, ]), forecastSt: PropTypes.object.isRequired, + curveSt: PropTypes.object.isRequired, }; NmrViewer.defaultProps = { diff --git a/src/components/forecast_viewer.js b/src/components/forecast_viewer.js index 5199ef6e..13c4c012 100644 --- a/src/components/forecast_viewer.js +++ b/src/components/forecast_viewer.js @@ -48,8 +48,18 @@ class ForecastViewer extends React.Component { } initForecastReducer() { - const { forecast, initForecastStatusAct, setUiViewerTypeAct } = this.props; - initForecastStatusAct(forecast); + const { + forecast, initForecastStatusAct, setUiViewerTypeAct, + } = this.props; + const predictionCurveIdx = ( + forecast + && forecast.predictions + && Number.isInteger(forecast.predictions.curveIdx) + ) ? forecast.predictions.curveIdx : null; + const payload = predictionCurveIdx === null + ? forecast + : { ...forecast, curveIdx: predictionCurveIdx }; + initForecastStatusAct(payload); if (forecast && forecast.predictions) { const { running, refreshed } = forecast.predictions; if (running || refreshed) setUiViewerTypeAct(LIST_UI_VIEWER_TYPE.ANALYSIS); @@ -69,7 +79,8 @@ class ForecastViewer extends React.Component { const { curveIdx } = curveSt; const { jcamps } = jcampSt; - const comparisons = jcamps[curveIdx].others; + const currentJcamp = jcamps && jcamps[curveIdx]; + const comparisons = currentJcamp && currentJcamp.others ? currentJcamp.others : []; return (
diff --git a/src/components/multi_jcamps_viewer.js b/src/components/multi_jcamps_viewer.js index d6ffd248..1f205dc7 100644 --- a/src/components/multi_jcamps_viewer.js +++ b/src/components/multi_jcamps_viewer.js @@ -12,12 +12,14 @@ import { withStyles } from '@mui/styles'; import PanelViewer from './panel/index'; import CmdBar from './cmd_bar/index'; import ViewerMulti from './d3_multi/index'; +import ForecastViewer from './forecast_viewer'; import { setAllCurves } from '../actions/curve'; import { addNewCylicVoltaPairPeak, addCylicVoltaMaxPeak, addCylicVoltaMinPeak, addCylicVoltaPecker, } from '../actions/cyclic_voltammetry'; import { LIST_LAYOUT } from '../constants/list_layout'; +import { LIST_UI_VIEWER_TYPE } from '../constants/list_ui'; import Format from '../helpers/format'; const styles = () => ({ @@ -56,6 +58,7 @@ class MultiJcampsViewer extends React.Component { // eslint-disable-line classes, curveSt, operations, entityFileNames, entities, userManualLink, molSvg, exactMass, layoutSt, integrationSt, descriptions, canChangeDescription, onDescriptionChanged, + forecast, uiSt, cLabel, } = this.props; if (!entities || entities.length === 0) return (
); @@ -66,25 +69,50 @@ class MultiJcampsViewer extends React.Component { // eslint-disable-line const { feature, topic } = entity; const { integrations } = integrationSt; const currentIntegration = integrations[curveIdx]; + const isNmr = Format.isNmrLayout(layoutSt); + const isIr = Format.isIrLayout(layoutSt); + const isUvvis = Format.isUvVisLayout(layoutSt) || Format.isHplcUvVisLayout(layoutSt); + const isXRD = Format.isXRDLayout(layoutSt); + const hasForecast = forecast && Object.keys(forecast).length > 0; + const showForecast = hasForecast && (isNmr || isIr || isUvvis || isXRD) + && uiSt.viewer === LIST_UI_VIEWER_TYPE.ANALYSIS; + const xLabel = feature.xUnit ? `X (${feature.xUnit})` : ''; + const yLabel = feature.yUnit ? `Y (${feature.yUnit})` : ''; return (
- + {showForecast ? ( + + ) : ( + + )} ( // eslint-disable-line entities: state.curve.listCurves, layoutSt: state.layout, integrationSt: state.integration.present, + uiSt: state.ui, } ); @@ -148,18 +177,20 @@ MultiJcampsViewer.propTypes = { descriptions: PropTypes.array.isRequired, canChangeDescription: PropTypes.bool.isRequired, onDescriptionChanged: PropTypes.func, + forecast: PropTypes.object.isRequired, + uiSt: PropTypes.object.isRequired, + cLabel: PropTypes.string, }; MultiJcampsViewer.defaultProps = { multiEntities: [], entityFileNames: [], molSvg: '', - cLabel: '', - xLabel: '', - yLabel: '', entities: [], descriptions: [], canChangeDescription: false, + forecast: {}, + cLabel: '', }; export default compose( diff --git a/src/index.js b/src/index.js index c689ebed..12107439 100644 --- a/src/index.js +++ b/src/index.js @@ -23,6 +23,7 @@ import compareIr2Jcamp from './__tests__/fixtures/compare_ir_2_jcamp'; import ramanJcamp from './__tests__/fixtures/raman_jcamp'; import msJcamp from './__tests__/fixtures/ms_jcamp'; import nmrResult from './__tests__/fixtures/nmr_result'; +import nmrResultAlt from './__tests__/fixtures/nmr_result_alt'; import irResult from './__tests__/fixtures/ir_result'; import Phenylalanin from './__tests__/fixtures/phenylalanin'; import compareUvVisJcamp from './__tests__/fixtures/compare_uv_vis_jcamp'; @@ -253,7 +254,7 @@ class DemoWriteIr extends React.Component { loadOthers() { const { showOthers, typ } = this.state; - const isIr = typ === 'ir'; + const isIr = typ === 'ir' || typ === 'multi ir'; const isXRD = typ === 'xrd'; const others = showOthers ? ( isIr ? [compIr1Entity, compIr2Entity] : ( @@ -418,7 +419,7 @@ class DemoWriteIr extends React.Component { predictOp({ multiplicity, curveSt, }) { - const { curveIdx } = curveSt; + const { curveIdx = 0 } = curveSt || {}; const { multiplicities } = multiplicity; const selectedMultiplicity = multiplicities[curveIdx]; const { stack, shift } = selectedMultiplicity; @@ -428,13 +429,16 @@ class DemoWriteIr extends React.Component { }) // console.log(targets) const { molecule, typ } = this.state; - const predictions = { running: true }; + const predictions = { running: true, curveIdx }; this.setState({ predictions }); // simulate fetching... - const result = typ === 'ir' ? irResult : nmrResult; + const selectNmrResult = (idx) => (idx % 2 === 0 ? nmrResult : nmrResultAlt); + const result = (typ === 'ir' || typ === 'multi ir') + ? irResult + : selectNmrResult(curveIdx); setTimeout(() => { - this.setState({ predictions: result }); + this.setState({ predictions: { ...result, curveIdx } }); }, 2000); } diff --git a/src/layer_init.js b/src/layer_init.js index 0c6d57da..f529ca7c 100644 --- a/src/layer_init.js +++ b/src/layer_init.js @@ -30,6 +30,7 @@ class LayerInit extends React.Component { this.initReducer = this.initReducer.bind(this); this.updateOthers = this.updateOthers.bind(this); this.updateMultiEntities = this.updateMultiEntities.bind(this); + this.hasSameMultiEntities = this.hasSameMultiEntities.bind(this); } componentDidMount() { @@ -42,7 +43,12 @@ class LayerInit extends React.Component { componentDidUpdate(prevProps) { this.normChange(prevProps); this.updateOthers(); - this.updateMultiEntities(); + const { entity, multiEntities } = this.props; + const multiEntitiesChanged = !this.hasSameMultiEntities(prevProps.multiEntities, multiEntities); + const entityChanged = prevProps.entity !== entity; + if (multiEntitiesChanged || entityChanged) { + this.updateMultiEntities(); + } } normChange(prevProps) { @@ -97,6 +103,19 @@ class LayerInit extends React.Component { addOthersAct(others); } + hasSameMultiEntities(prevMultiEntities, nextMultiEntities) { + if (prevMultiEntities === nextMultiEntities) return true; + const prevArray = Array.isArray(prevMultiEntities) ? prevMultiEntities : null; + const nextArray = Array.isArray(nextMultiEntities) ? nextMultiEntities : null; + if (!prevArray && !nextArray) return true; + if (!prevArray || !nextArray) return false; + if (prevArray.length !== nextArray.length) return false; + for (let idx = 0; idx < prevArray.length; idx += 1) { + if (prevArray[idx] !== nextArray[idx]) return false; + } + return true; + } + updateMultiEntities() { const { multiEntities, setAllCurvesAct, entity } = this.props; const isMultiSpectra = Array.isArray(multiEntities) && multiEntities.length > 1; @@ -140,6 +159,8 @@ class LayerInit extends React.Component { molSvg={molSvg} exactMass={exactMass} operations={operations} + forecast={forecast} + cLabel={cLabel} descriptions={descriptions} canChangeDescription={canChangeDescription} onDescriptionChanged={onDescriptionChanged} @@ -154,6 +175,8 @@ class LayerInit extends React.Component { molSvg={molSvg} exactMass={exactMass} operations={operations} + forecast={forecast} + cLabel={cLabel} descriptions={descriptions} canChangeDescription={canChangeDescription} onDescriptionChanged={onDescriptionChanged} diff --git a/src/reducers/reducer_curve.js b/src/reducers/reducer_curve.js index 16d400cc..8d167753 100644 --- a/src/reducers/reducer_curve.js +++ b/src/reducers/reducer_curve.js @@ -18,12 +18,22 @@ const setAllCurves = (state, action) => { const { topic, feature, hasEdit, integration, multiplicity, } = extractParams(entity, { isEdit: true }); + const simulation = entity && entity.features ? entity.features.simulation : undefined; // const layout = entity.layout; const { layout } = entity; const maxminPeak = Convert2MaxMinPeak(layout, feature, 0); const color = Format.mutiEntitiesColors(idx); return { - layout, topic, feature, hasEdit, integration, multiplicity, maxminPeak, color, curveIdx: idx, + layout, + topic, + feature, + hasEdit, + integration, + multiplicity, + simulation, + maxminPeak, + color, + curveIdx: idx, }; }); diff --git a/src/reducers/reducer_forecast.js b/src/reducers/reducer_forecast.js index fb1e135e..ecc749b2 100644 --- a/src/reducers/reducer_forecast.js +++ b/src/reducers/reducer_forecast.js @@ -6,8 +6,17 @@ const initialState = { outline: {}, output: { result: [] }, }, + predictionsByCurve: {}, }; +const toCurveIdx = (input) => (Number.isInteger(input) ? input : 0); + +const getPredictionsByCurve = (state) => (state.predictionsByCurve || {}); + +const getPredictionsForCurve = (state, curveIdx) => ( + getPredictionsByCurve(state)[curveIdx] || state.predictions +); + const updateIrResl = (stResl, plPred) => { const { sma, identity, value } = plPred; const { svgs } = stResl; @@ -24,21 +33,30 @@ const updateIrResl = (stResl, plPred) => { }; const updateIrStatus = (state, action) => { - const { predictions } = action.payload; - const { outline, output } = state.predictions; + const { predictions, curveIdx } = action.payload; + const targetIdx = toCurveIdx(curveIdx); + const targetPredictions = getPredictionsForCurve(state, targetIdx); + const { outline, output } = targetPredictions; const stResl = output.result[0]; const nextResl = updateIrResl(stResl, predictions); + const nextPredictions = { + outline, + output: { + result: [nextResl], + }, + }; + const predictionsByCurve = Object.assign( + {}, + getPredictionsByCurve(state), + { [targetIdx]: nextPredictions }, + ); return Object.assign( {}, state, { - predictions: { - outline, - output: { - result: [nextResl], - }, - }, + predictions: nextPredictions, + predictionsByCurve, }, ); }; @@ -64,41 +82,67 @@ const updateNmrResl = (stResl, plPred) => { }; const updateNmrStatus = (state, action) => { - const { predictions } = action.payload; - const { outline, output } = state.predictions; + const { predictions, curveIdx } = action.payload; + const targetIdx = toCurveIdx(curveIdx); + const targetPredictions = getPredictionsForCurve(state, targetIdx); + const { outline, output } = targetPredictions; const stResl = output.result[0]; const nextResl = updateNmrResl(stResl, predictions); + const nextPredictions = { + outline, + output: { + result: [nextResl], + }, + }; + const predictionsByCurve = Object.assign( + {}, + getPredictionsByCurve(state), + { [targetIdx]: nextPredictions }, + ); - const newSt = Object.assign( + return Object.assign( {}, state, { - predictions: { - outline, - output: { - result: [nextResl], - }, - }, + predictions: nextPredictions, + predictionsByCurve, }, ); - return newSt; }; const forecastReducer = (state = initialState, action) => { switch (action.type) { case FORECAST.INIT_STATUS: if (!action.payload) return state; - return Object.assign( - {}, - action.payload, - ); + { + const { curveIdx, ...payloadRest } = action.payload; + const nextPredictions = payloadRest.predictions || state.predictions; + const nextState = Object.assign( + {}, + state, + payloadRest, + ); + if (!Number.isInteger(curveIdx)) { + return nextState; + } + const predictionsByCurve = Object.assign( + {}, + getPredictionsByCurve(state), + nextPredictions ? { [curveIdx]: nextPredictions } : {}, + ); + return Object.assign({}, nextState, { predictionsByCurve }); + } case FORECAST.SET_IR_STATUS: return updateIrStatus(state, action); case FORECAST.SET_NMR_STATUS: return updateNmrStatus(state, action); case FORECAST.CLEAR_STATUS: - case MANAGER.RESETALL: return initialState; + case MANAGER.RESETALL: + if (action.payload && action.payload.resetForecast) { + return initialState; + } + return state; default: return state; } diff --git a/src/sagas/saga_multi_entities.js b/src/sagas/saga_multi_entities.js index 8984b128..88fd6d36 100644 --- a/src/sagas/saga_multi_entities.js +++ b/src/sagas/saga_multi_entities.js @@ -6,6 +6,7 @@ import { } from '../constants/action_type'; import { LIST_LAYOUT } from '../constants/list_layout'; +import Format from '../helpers/format'; const getLayoutSt = (state) => state.layout; const getCurveSt = (state) => state.curve; @@ -139,9 +140,34 @@ function* setInitIntegrations(action) { // eslint-disable-line } } +function* setSimulationForCurve(action) { // eslint-disable-line + const layoutSt = yield select(getLayoutSt); + if (!Format.isNmrLayout(layoutSt)) return; + + const curveSt = yield select(getCurveSt); + const { listCurves, curveIdx } = curveSt; + if (!Array.isArray(listCurves) || listCurves.length === 0) return; + + const targetIdx = Number.isInteger(action.payload) ? action.payload : curveIdx; + const targetCurve = listCurves[targetIdx]; + if (!targetCurve || !targetCurve.simulation) { + yield put({ + type: SIMULATION.RESET_ALL_RDC, + payload: { nmrSimPeaks: [] }, + }); + return; + } + + yield put({ + type: SIMULATION.RESET_ALL_RDC, + payload: targetCurve.simulation, + }); +} + const multiEntitiesSagas = [ takeEvery(CURVE.SET_ALL_CURVES, setCyclicVoltametry), takeEvery(CURVE.SET_ALL_CURVES, setInitIntegrations), + takeEvery(CURVE.SELECT_WORKING_CURVE, setSimulationForCurve), takeEvery(CYCLIC_VOLTA_METRY.SET_FACTOR, setCyclicVoltametryRef), ]; From 5ef1d75773fc1d3902183584bb4979dc7431e1b5 Mon Sep 17 00:00:00 2001 From: Nicolass67 Date: Thu, 29 Jan 2026 13:49:34 +0100 Subject: [PATCH 3/4] dist folder --- dist/actions/axes.js | 19 + dist/actions/curve.js | 22 + dist/actions/cyclic_voltammetry.js | 72 ++ dist/actions/detector.js | 14 + dist/actions/edit_peak.js | 22 + dist/actions/forecast.js | 27 + dist/actions/integration.js | 24 + dist/actions/jcamp.js | 27 + dist/actions/layout.js | 14 + dist/actions/manager.js | 42 + dist/actions/meta.js | 17 + dist/actions/multiplicity.js | 39 + dist/actions/scan.js | 22 + dist/actions/shift.js | 19 + dist/actions/status.js | 22 + dist/actions/submit.js | 27 + dist/actions/threshold.js | 32 + dist/actions/ui.js | 43 + dist/actions/wavelength.js | 14 + dist/app.js | 133 +++ dist/components/cmd_bar/01_viewer.js | 87 ++ dist/components/cmd_bar/02_zoom.js | 79 ++ dist/components/cmd_bar/03_peak.js | 187 ++++ dist/components/cmd_bar/04_integration.js | 213 ++++ dist/components/cmd_bar/05_multiplicity.js | 161 +++ dist/components/cmd_bar/06_undo_redo.js | 87 ++ dist/components/cmd_bar/07_pecker.js | 194 ++++ dist/components/cmd_bar/common.js | 127 +++ dist/components/cmd_bar/index.js | 82 ++ dist/components/cmd_bar/r01_layout.js | 354 +++++++ dist/components/cmd_bar/r02_scan.js | 133 +++ dist/components/cmd_bar/r03_threshold.js | 162 +++ dist/components/cmd_bar/r04_submit.js | 262 +++++ dist/components/cmd_bar/r05_submit_btn.js | 155 +++ dist/components/cmd_bar/r06_predict_btn.js | 253 +++++ dist/components/cmd_bar/r07_wavelength_btn.js | 89 ++ dist/components/cmd_bar/r08_change_axes.js | 173 ++++ dist/components/cmd_bar/r09_detector.js | 107 ++ dist/components/cmd_bar/tri_btn.js | 131 +++ dist/components/common/chem.js | 115 +++ dist/components/common/comps.js | 17 + dist/components/common/draw.js | 51 + dist/components/d3_line/index.js | 234 +++++ dist/components/d3_line/line_focus.js | 684 +++++++++++++ dist/components/d3_multi/index.js | 254 +++++ dist/components/d3_multi/multi_focus.js | 909 +++++++++++++++++ dist/components/d3_rect/index.js | 152 +++ dist/components/d3_rect/rect_focus.js | 225 +++++ dist/components/forecast/comps.js | 241 +++++ dist/components/forecast/ir_comps.js | 159 +++ dist/components/forecast/ir_viewer.js | 141 +++ dist/components/forecast/nmr_comps.js | 162 +++ dist/components/forecast/nmr_viewer.js | 138 +++ dist/components/forecast/section_loading.js | 62 ++ dist/components/forecast_viewer.js | 155 +++ dist/components/multi_jcamps_viewer.js | 209 ++++ dist/components/panel/compare.js | 278 ++++++ .../components/panel/cyclic_voltamery_data.js | 377 +++++++ dist/components/panel/graph_selection.js | 262 +++++ dist/components/panel/index.js | 170 ++++ dist/components/panel/info.js | 494 +++++++++ dist/components/panel/multiplicity.js | 312 ++++++ .../components/panel/multiplicity_coupling.js | 139 +++ dist/components/panel/multiplicity_select.js | 89 ++ dist/components/panel/peaks.js | 241 +++++ dist/constants/action_type.js | 150 +++ dist/constants/list_axes.js | 17 + dist/constants/list_detectors.js | 15 + dist/constants/list_layout.js | 31 + dist/constants/list_shift.js | 421 ++++++++ dist/constants/list_ui.js | 35 + dist/constants/list_wavelength.js | 31 + dist/fn.js | 23 + dist/helpers/brush.js | 100 ++ dist/helpers/calc.js | 15 + dist/helpers/carbonFeatures.js | 51 + dist/helpers/cfg.js | 65 ++ dist/helpers/chem.js | 937 ++++++++++++++++++ dist/helpers/compass.js | 160 +++ dist/helpers/converter.js | 99 ++ dist/helpers/extractParams.js | 86 ++ dist/helpers/extractPeaksEdit.js | 76 ++ dist/helpers/focus.js | 10 + dist/helpers/format.js | 685 +++++++++++++ dist/helpers/init.js | 69 ++ dist/helpers/integration.js | 58 ++ dist/helpers/mount.js | 110 ++ dist/helpers/multiplicity.js | 42 + dist/helpers/multiplicity_calc.js | 102 ++ dist/helpers/multiplicity_complat.js | 100 ++ dist/helpers/multiplicity_manual.js | 125 +++ dist/helpers/multiplicity_verify_basic.js | 249 +++++ dist/helpers/shift.js | 35 + dist/helpers/zoom.js | 22 + dist/index.js | 859 ++++++++++++++++ dist/layer_content.js | 105 ++ dist/layer_init.js | 281 ++++++ dist/layer_prism.js | 151 +++ dist/reducers/index.js | 51 + dist/reducers/reducer_axes.js | 59 ++ dist/reducers/reducer_curve.js | 82 ++ dist/reducers/reducer_detector.js | 52 + dist/reducers/reducer_edit_peak.js | 235 +++++ dist/reducers/reducer_forecast.js | 161 +++ dist/reducers/reducer_integration.js | 236 +++++ dist/reducers/reducer_jcamp.js | 102 ++ dist/reducers/reducer_layout.js | 24 + dist/reducers/reducer_manager.js | 19 + dist/reducers/reducer_meta.js | 42 + dist/reducers/reducer_multiplicity.js | 201 ++++ dist/reducers/reducer_scan.js | 48 + dist/reducers/reducer_shift.js | 245 +++++ dist/reducers/reducer_simulation.js | 27 + dist/reducers/reducer_status.js | 47 + dist/reducers/reducer_submit.js | 61 ++ dist/reducers/reducer_threshold.js | 224 +++++ dist/reducers/reducer_ui.js | 51 + dist/reducers/reducer_voltammetry.js | 574 +++++++++++ dist/reducers/reducer_wavelength.js | 22 + dist/reducers/undo_redo_config.js | 17 + dist/sagas/index.js | 17 + dist/sagas/saga_edit_peak.js | 75 ++ dist/sagas/saga_manager.js | 97 ++ dist/sagas/saga_meta.js | 44 + dist/sagas/saga_multi_entities.js | 202 ++++ dist/sagas/saga_multiplicity.js | 379 +++++++ dist/sagas/saga_ui.js | 321 ++++++ dist/setupTests.js | 8 + dist/third_party/jAnalyzer.js | 590 +++++++++++ dist/third_party/peakInterval.js | 105 ++ 130 files changed, 19690 insertions(+) create mode 100644 dist/actions/axes.js create mode 100644 dist/actions/curve.js create mode 100644 dist/actions/cyclic_voltammetry.js create mode 100644 dist/actions/detector.js create mode 100644 dist/actions/edit_peak.js create mode 100644 dist/actions/forecast.js create mode 100644 dist/actions/integration.js create mode 100644 dist/actions/jcamp.js create mode 100644 dist/actions/layout.js create mode 100644 dist/actions/manager.js create mode 100644 dist/actions/meta.js create mode 100644 dist/actions/multiplicity.js create mode 100644 dist/actions/scan.js create mode 100644 dist/actions/shift.js create mode 100644 dist/actions/status.js create mode 100644 dist/actions/submit.js create mode 100644 dist/actions/threshold.js create mode 100644 dist/actions/ui.js create mode 100644 dist/actions/wavelength.js create mode 100644 dist/app.js create mode 100644 dist/components/cmd_bar/01_viewer.js create mode 100644 dist/components/cmd_bar/02_zoom.js create mode 100644 dist/components/cmd_bar/03_peak.js create mode 100644 dist/components/cmd_bar/04_integration.js create mode 100644 dist/components/cmd_bar/05_multiplicity.js create mode 100644 dist/components/cmd_bar/06_undo_redo.js create mode 100644 dist/components/cmd_bar/07_pecker.js create mode 100644 dist/components/cmd_bar/common.js create mode 100644 dist/components/cmd_bar/index.js create mode 100644 dist/components/cmd_bar/r01_layout.js create mode 100644 dist/components/cmd_bar/r02_scan.js create mode 100644 dist/components/cmd_bar/r03_threshold.js create mode 100644 dist/components/cmd_bar/r04_submit.js create mode 100644 dist/components/cmd_bar/r05_submit_btn.js create mode 100644 dist/components/cmd_bar/r06_predict_btn.js create mode 100644 dist/components/cmd_bar/r07_wavelength_btn.js create mode 100644 dist/components/cmd_bar/r08_change_axes.js create mode 100644 dist/components/cmd_bar/r09_detector.js create mode 100644 dist/components/cmd_bar/tri_btn.js create mode 100644 dist/components/common/chem.js create mode 100644 dist/components/common/comps.js create mode 100644 dist/components/common/draw.js create mode 100644 dist/components/d3_line/index.js create mode 100644 dist/components/d3_line/line_focus.js create mode 100644 dist/components/d3_multi/index.js create mode 100644 dist/components/d3_multi/multi_focus.js create mode 100644 dist/components/d3_rect/index.js create mode 100644 dist/components/d3_rect/rect_focus.js create mode 100644 dist/components/forecast/comps.js create mode 100644 dist/components/forecast/ir_comps.js create mode 100644 dist/components/forecast/ir_viewer.js create mode 100644 dist/components/forecast/nmr_comps.js create mode 100644 dist/components/forecast/nmr_viewer.js create mode 100644 dist/components/forecast/section_loading.js create mode 100644 dist/components/forecast_viewer.js create mode 100644 dist/components/multi_jcamps_viewer.js create mode 100644 dist/components/panel/compare.js create mode 100644 dist/components/panel/cyclic_voltamery_data.js create mode 100644 dist/components/panel/graph_selection.js create mode 100644 dist/components/panel/index.js create mode 100644 dist/components/panel/info.js create mode 100644 dist/components/panel/multiplicity.js create mode 100644 dist/components/panel/multiplicity_coupling.js create mode 100644 dist/components/panel/multiplicity_select.js create mode 100644 dist/components/panel/peaks.js create mode 100644 dist/constants/action_type.js create mode 100644 dist/constants/list_axes.js create mode 100644 dist/constants/list_detectors.js create mode 100644 dist/constants/list_layout.js create mode 100644 dist/constants/list_shift.js create mode 100644 dist/constants/list_ui.js create mode 100644 dist/constants/list_wavelength.js create mode 100644 dist/fn.js create mode 100644 dist/helpers/brush.js create mode 100644 dist/helpers/calc.js create mode 100644 dist/helpers/carbonFeatures.js create mode 100644 dist/helpers/cfg.js create mode 100644 dist/helpers/chem.js create mode 100644 dist/helpers/compass.js create mode 100644 dist/helpers/converter.js create mode 100644 dist/helpers/extractParams.js create mode 100644 dist/helpers/extractPeaksEdit.js create mode 100644 dist/helpers/focus.js create mode 100644 dist/helpers/format.js create mode 100644 dist/helpers/init.js create mode 100644 dist/helpers/integration.js create mode 100644 dist/helpers/mount.js create mode 100644 dist/helpers/multiplicity.js create mode 100644 dist/helpers/multiplicity_calc.js create mode 100644 dist/helpers/multiplicity_complat.js create mode 100644 dist/helpers/multiplicity_manual.js create mode 100644 dist/helpers/multiplicity_verify_basic.js create mode 100644 dist/helpers/shift.js create mode 100644 dist/helpers/zoom.js create mode 100644 dist/index.js create mode 100644 dist/layer_content.js create mode 100644 dist/layer_init.js create mode 100644 dist/layer_prism.js create mode 100644 dist/reducers/index.js create mode 100644 dist/reducers/reducer_axes.js create mode 100644 dist/reducers/reducer_curve.js create mode 100644 dist/reducers/reducer_detector.js create mode 100644 dist/reducers/reducer_edit_peak.js create mode 100644 dist/reducers/reducer_forecast.js create mode 100644 dist/reducers/reducer_integration.js create mode 100644 dist/reducers/reducer_jcamp.js create mode 100644 dist/reducers/reducer_layout.js create mode 100644 dist/reducers/reducer_manager.js create mode 100644 dist/reducers/reducer_meta.js create mode 100644 dist/reducers/reducer_multiplicity.js create mode 100644 dist/reducers/reducer_scan.js create mode 100644 dist/reducers/reducer_shift.js create mode 100644 dist/reducers/reducer_simulation.js create mode 100644 dist/reducers/reducer_status.js create mode 100644 dist/reducers/reducer_submit.js create mode 100644 dist/reducers/reducer_threshold.js create mode 100644 dist/reducers/reducer_ui.js create mode 100644 dist/reducers/reducer_voltammetry.js create mode 100644 dist/reducers/reducer_wavelength.js create mode 100644 dist/reducers/undo_redo_config.js create mode 100644 dist/sagas/index.js create mode 100644 dist/sagas/saga_edit_peak.js create mode 100644 dist/sagas/saga_manager.js create mode 100644 dist/sagas/saga_meta.js create mode 100644 dist/sagas/saga_multi_entities.js create mode 100644 dist/sagas/saga_multiplicity.js create mode 100644 dist/sagas/saga_ui.js create mode 100644 dist/setupTests.js create mode 100644 dist/third_party/jAnalyzer.js create mode 100644 dist/third_party/peakInterval.js diff --git a/dist/actions/axes.js b/dist/actions/axes.js new file mode 100644 index 00000000..3cde6370 --- /dev/null +++ b/dist/actions/axes.js @@ -0,0 +1,19 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.updateYAxis = exports.updateXAxis = void 0; +var _action_type = require("../constants/action_type"); +const updateXAxis = payload => ({ + type: _action_type.AXES.UPDATE_X_AXIS, + payload +}); +exports.updateXAxis = updateXAxis; +const updateYAxis = payload => ({ + type: _action_type.AXES.UPDATE_Y_AXIS, + payload +}); + +// eslint-disable-line +exports.updateYAxis = updateYAxis; \ No newline at end of file diff --git a/dist/actions/curve.js b/dist/actions/curve.js new file mode 100644 index 00000000..85bd0062 --- /dev/null +++ b/dist/actions/curve.js @@ -0,0 +1,22 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.toggleShowAllCurves = exports.setAllCurves = exports.selectCurve = void 0; +var _action_type = require("../constants/action_type"); +const selectCurve = payload => ({ + type: _action_type.CURVE.SELECT_WORKING_CURVE, + payload +}); +exports.selectCurve = selectCurve; +const setAllCurves = payload => ({ + type: _action_type.CURVE.SET_ALL_CURVES, + payload +}); +exports.setAllCurves = setAllCurves; +const toggleShowAllCurves = payload => ({ + type: _action_type.CURVE.SET_SHOULD_SHOW_ALL_CURVES, + payload +}); +exports.toggleShowAllCurves = toggleShowAllCurves; \ No newline at end of file diff --git a/dist/actions/cyclic_voltammetry.js b/dist/actions/cyclic_voltammetry.js new file mode 100644 index 00000000..3f53977d --- /dev/null +++ b/dist/actions/cyclic_voltammetry.js @@ -0,0 +1,72 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.setWorkWithMaxPeak = exports.setCylicVoltaRefFactor = exports.setCylicVoltaRef = exports.selectRefPeaks = exports.selectPairPeak = exports.removeCylicVoltaPecker = exports.removeCylicVoltaPairPeak = exports.removeCylicVoltaMinPeak = exports.removeCylicVoltaMaxPeak = exports.addNewCylicVoltaPairPeak = exports.addCylicVoltaPecker = exports.addCylicVoltaMinPeak = exports.addCylicVoltaMaxPeak = void 0; +var _action_type = require("../constants/action_type"); +const addNewCylicVoltaPairPeak = payload => ({ + type: _action_type.CYCLIC_VOLTA_METRY.ADD_PAIR_PEAKS, + payload +}); +exports.addNewCylicVoltaPairPeak = addNewCylicVoltaPairPeak; +const removeCylicVoltaPairPeak = payload => ({ + type: _action_type.CYCLIC_VOLTA_METRY.REMOVE_PAIR_PEAKS, + payload +}); +exports.removeCylicVoltaPairPeak = removeCylicVoltaPairPeak; +const addCylicVoltaMaxPeak = payload => ({ + type: _action_type.CYCLIC_VOLTA_METRY.ADD_MAX_PEAK, + payload +}); +exports.addCylicVoltaMaxPeak = addCylicVoltaMaxPeak; +const removeCylicVoltaMaxPeak = payload => ({ + type: _action_type.CYCLIC_VOLTA_METRY.REMOVE_MAX_PEAK, + payload +}); +exports.removeCylicVoltaMaxPeak = removeCylicVoltaMaxPeak; +const addCylicVoltaMinPeak = payload => ({ + type: _action_type.CYCLIC_VOLTA_METRY.ADD_MIN_PEAK, + payload +}); +exports.addCylicVoltaMinPeak = addCylicVoltaMinPeak; +const removeCylicVoltaMinPeak = payload => ({ + type: _action_type.CYCLIC_VOLTA_METRY.REMOVE_MIN_PEAK, + payload +}); +exports.removeCylicVoltaMinPeak = removeCylicVoltaMinPeak; +const setWorkWithMaxPeak = payload => ({ + type: _action_type.CYCLIC_VOLTA_METRY.WORK_WITH_MAX_PEAK, + payload +}); +exports.setWorkWithMaxPeak = setWorkWithMaxPeak; +const selectPairPeak = payload => ({ + type: _action_type.CYCLIC_VOLTA_METRY.SELECT_PAIR_PEAK, + payload +}); +exports.selectPairPeak = selectPairPeak; +const addCylicVoltaPecker = payload => ({ + type: _action_type.CYCLIC_VOLTA_METRY.ADD_PECKER, + payload +}); +exports.addCylicVoltaPecker = addCylicVoltaPecker; +const removeCylicVoltaPecker = payload => ({ + type: _action_type.CYCLIC_VOLTA_METRY.REMOVE_PECKER, + payload +}); +exports.removeCylicVoltaPecker = removeCylicVoltaPecker; +const selectRefPeaks = payload => ({ + type: _action_type.CYCLIC_VOLTA_METRY.SELECT_REF_PEAK, + payload +}); +exports.selectRefPeaks = selectRefPeaks; +const setCylicVoltaRefFactor = payload => ({ + type: _action_type.CYCLIC_VOLTA_METRY.SET_FACTOR, + payload +}); +exports.setCylicVoltaRefFactor = setCylicVoltaRefFactor; +const setCylicVoltaRef = payload => ({ + type: _action_type.CYCLIC_VOLTA_METRY.SET_REF, + payload +}); +exports.setCylicVoltaRef = setCylicVoltaRef; \ No newline at end of file diff --git a/dist/actions/detector.js b/dist/actions/detector.js new file mode 100644 index 00000000..4736ec21 --- /dev/null +++ b/dist/actions/detector.js @@ -0,0 +1,14 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.updateDetector = void 0; +var _action_type = require("../constants/action_type"); +/* eslint-disable import/prefer-default-export */ + +const updateDetector = payload => ({ + type: _action_type.SEC.UPDATE_DETECTOR, + payload +}); +exports.updateDetector = updateDetector; \ No newline at end of file diff --git a/dist/actions/edit_peak.js b/dist/actions/edit_peak.js new file mode 100644 index 00000000..cbb80814 --- /dev/null +++ b/dist/actions/edit_peak.js @@ -0,0 +1,22 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.rmFromPosList = exports.rmFromNegList = exports.clearAllPeaks = void 0; +var _action_type = require("../constants/action_type"); +const rmFromPosList = payload => ({ + type: _action_type.EDITPEAK.RM_POSITIVE, + payload +}); +exports.rmFromPosList = rmFromPosList; +const rmFromNegList = payload => ({ + type: _action_type.EDITPEAK.RM_NEGATIVE, + payload +}); +exports.rmFromNegList = rmFromNegList; +const clearAllPeaks = payload => ({ + type: _action_type.EDITPEAK.CLEAR_ALL, + payload +}); +exports.clearAllPeaks = clearAllPeaks; \ No newline at end of file diff --git a/dist/actions/forecast.js b/dist/actions/forecast.js new file mode 100644 index 00000000..6ef4cae6 --- /dev/null +++ b/dist/actions/forecast.js @@ -0,0 +1,27 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.setNmrStatus = exports.setIrStatus = exports.initForecastStatus = exports.clearForecastStatus = void 0; +var _action_type = require("../constants/action_type"); +const initForecastStatus = payload => ({ + type: _action_type.FORECAST.INIT_STATUS, + payload +}); +exports.initForecastStatus = initForecastStatus; +const setIrStatus = payload => ({ + type: _action_type.FORECAST.SET_IR_STATUS, + payload +}); +exports.setIrStatus = setIrStatus; +const setNmrStatus = payload => ({ + type: _action_type.FORECAST.SET_NMR_STATUS, + payload +}); +exports.setNmrStatus = setNmrStatus; +const clearForecastStatus = payload => ({ + type: _action_type.FORECAST.CLEAR_STATUS, + payload +}); +exports.clearForecastStatus = clearForecastStatus; \ No newline at end of file diff --git a/dist/actions/integration.js b/dist/actions/integration.js new file mode 100644 index 00000000..f81706c4 --- /dev/null +++ b/dist/actions/integration.js @@ -0,0 +1,24 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.sweepIntegration = exports.setIntegrationFkr = exports.clearIntegrationAll = void 0; +var _action_type = require("../constants/action_type"); +const sweepIntegration = payload => ({ + type: _action_type.INTEGRATION.SWEEP, + payload +}); +exports.sweepIntegration = sweepIntegration; +const setIntegrationFkr = payload => ({ + type: _action_type.INTEGRATION.SET_FKR, + payload +}); +exports.setIntegrationFkr = setIntegrationFkr; +const clearIntegrationAll = payload => ({ + type: _action_type.INTEGRATION.CLEAR_ALL, + payload +}); + +// eslint-disable-line +exports.clearIntegrationAll = clearIntegrationAll; \ No newline at end of file diff --git a/dist/actions/jcamp.js b/dist/actions/jcamp.js new file mode 100644 index 00000000..302fb464 --- /dev/null +++ b/dist/actions/jcamp.js @@ -0,0 +1,27 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.toggleShow = exports.rmOthersOne = exports.clearAll = exports.addOthers = void 0; +var _action_type = require("../constants/action_type"); +const addOthers = payload => ({ + type: _action_type.JCAMP.ADD_OTHERS, + payload +}); +exports.addOthers = addOthers; +const rmOthersOne = payload => ({ + type: _action_type.JCAMP.RM_OTHERS_ONE, + payload +}); +exports.rmOthersOne = rmOthersOne; +const toggleShow = payload => ({ + type: _action_type.JCAMP.TOGGLE_SHOW, + payload +}); +exports.toggleShow = toggleShow; +const clearAll = payload => ({ + type: _action_type.JCAMP.CLEAR_ALL, + payload +}); +exports.clearAll = clearAll; \ No newline at end of file diff --git a/dist/actions/layout.js b/dist/actions/layout.js new file mode 100644 index 00000000..7651a640 --- /dev/null +++ b/dist/actions/layout.js @@ -0,0 +1,14 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.updateLayout = void 0; +var _action_type = require("../constants/action_type"); +const updateLayout = payload => ({ + type: _action_type.LAYOUT.UPDATE, + payload +}); + +// eslint-disable-line +exports.updateLayout = updateLayout; \ No newline at end of file diff --git a/dist/actions/manager.js b/dist/actions/manager.js new file mode 100644 index 00000000..f2effe9c --- /dev/null +++ b/dist/actions/manager.js @@ -0,0 +1,42 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.resetMultiplicity = exports.resetInitNmr = exports.resetInitMs = exports.resetInitCommonWithIntergation = exports.resetInitCommon = exports.resetDetector = exports.resetAll = void 0; +var _action_type = require("../constants/action_type"); +const resetAll = payload => ({ + type: _action_type.MANAGER.RESETALL, + payload +}); +exports.resetAll = resetAll; +const resetInitCommon = payload => ({ + type: _action_type.MANAGER.RESET_INIT_COMMON, + payload +}); +exports.resetInitCommon = resetInitCommon; +const resetInitNmr = payload => ({ + type: _action_type.MANAGER.RESET_INIT_NMR, + payload +}); +exports.resetInitNmr = resetInitNmr; +const resetInitMs = payload => ({ + type: _action_type.MANAGER.RESET_INIT_MS, + payload +}); +exports.resetInitMs = resetInitMs; +const resetInitCommonWithIntergation = payload => ({ + type: _action_type.MANAGER.RESET_INIT_COMMON_WITH_INTERGATION, + payload +}); +exports.resetInitCommonWithIntergation = resetInitCommonWithIntergation; +const resetDetector = () => ({ + type: _action_type.MANAGER.RESET_DETECTOR +}); +exports.resetDetector = resetDetector; +const resetMultiplicity = () => ({ + type: _action_type.MANAGER.RESET_MULTIPLICITY +}); + +// eslint-disable-line +exports.resetMultiplicity = resetMultiplicity; \ No newline at end of file diff --git a/dist/actions/meta.js b/dist/actions/meta.js new file mode 100644 index 00000000..dce5acf9 --- /dev/null +++ b/dist/actions/meta.js @@ -0,0 +1,17 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.updateMetaPeaks = exports.updateDSCMetaData = void 0; +var _action_type = require("../constants/action_type"); +const updateMetaPeaks = payload => ({ + type: _action_type.META.UPDATE_PEAKS, + payload +}); +exports.updateMetaPeaks = updateMetaPeaks; +const updateDSCMetaData = payload => ({ + type: _action_type.META.UPDATE_META_DATA, + payload +}); +exports.updateDSCMetaData = updateDSCMetaData; \ No newline at end of file diff --git a/dist/actions/multiplicity.js b/dist/actions/multiplicity.js new file mode 100644 index 00000000..d057f481 --- /dev/null +++ b/dist/actions/multiplicity.js @@ -0,0 +1,39 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.updateMpyJ = exports.selectMpyType = exports.rmMpyPeakByPanel = exports.resetMpyOne = exports.clickMpyOne = exports.clearMpyAll = void 0; +var _action_type = require("../constants/action_type"); +const clickMpyOne = payload => ({ + type: _action_type.MULTIPLICITY.ONE_CLICK, + payload +}); +exports.clickMpyOne = clickMpyOne; +const rmMpyPeakByPanel = payload => ({ + type: _action_type.MULTIPLICITY.PEAK_RM_BY_PANEL, + payload +}); +exports.rmMpyPeakByPanel = rmMpyPeakByPanel; +const selectMpyType = payload => ({ + type: _action_type.MULTIPLICITY.TYPE_SELECT, + payload +}); +exports.selectMpyType = selectMpyType; +const clearMpyAll = payload => ({ + type: _action_type.MULTIPLICITY.CLEAR_ALL, + payload +}); +exports.clearMpyAll = clearMpyAll; +const resetMpyOne = payload => ({ + type: _action_type.MULTIPLICITY.RESET_ONE, + payload +}); +exports.resetMpyOne = resetMpyOne; +const updateMpyJ = payload => ({ + type: _action_type.MULTIPLICITY.UPDATE_J, + payload +}); + +// eslint-disable-line +exports.updateMpyJ = updateMpyJ; \ No newline at end of file diff --git a/dist/actions/scan.js b/dist/actions/scan.js new file mode 100644 index 00000000..c8069390 --- /dev/null +++ b/dist/actions/scan.js @@ -0,0 +1,22 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.toggleScanIsAuto = exports.setScanTarget = exports.resetScanTarget = void 0; +var _action_type = require("../constants/action_type"); +const setScanTarget = payload => ({ + type: _action_type.SCAN.SET_TARGET, + payload +}); +exports.setScanTarget = setScanTarget; +const resetScanTarget = () => ({ + type: _action_type.SCAN.SET_TARGET, + payload: false +}); +exports.resetScanTarget = resetScanTarget; +const toggleScanIsAuto = payload => ({ + type: _action_type.SCAN.TOGGLE_ISAUTO, + payload +}); +exports.toggleScanIsAuto = toggleScanIsAuto; \ No newline at end of file diff --git a/dist/actions/shift.js b/dist/actions/shift.js new file mode 100644 index 00000000..62adf12a --- /dev/null +++ b/dist/actions/shift.js @@ -0,0 +1,19 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.setShiftRef = exports.rmShiftPeak = void 0; +var _action_type = require("../constants/action_type"); +const setShiftRef = payload => ({ + type: _action_type.SHIFT.SET_REF, + payload +}); +exports.setShiftRef = setShiftRef; +const rmShiftPeak = () => ({ + type: _action_type.SHIFT.RM_PEAK, + payload: null +}); + +// eslint-disable-line +exports.rmShiftPeak = rmShiftPeak; \ No newline at end of file diff --git a/dist/actions/status.js b/dist/actions/status.js new file mode 100644 index 00000000..d7efff6f --- /dev/null +++ b/dist/actions/status.js @@ -0,0 +1,22 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.toggleSubmitBtn = exports.toggleAllBtn = exports.enableAllBtn = void 0; +var _action_type = require("../constants/action_type"); +const toggleSubmitBtn = () => ({ + type: _action_type.STATUS.TOGGLEBTNSUBMIT, + payload: [] +}); +exports.toggleSubmitBtn = toggleSubmitBtn; +const toggleAllBtn = () => ({ + type: _action_type.STATUS.TOGGLEBTNALL, + payload: [] +}); +exports.toggleAllBtn = toggleAllBtn; +const enableAllBtn = () => ({ + type: _action_type.STATUS.ENABLEBTNALL, + payload: [] +}); +exports.enableAllBtn = enableAllBtn; \ No newline at end of file diff --git a/dist/actions/submit.js b/dist/actions/submit.js new file mode 100644 index 00000000..66611588 --- /dev/null +++ b/dist/actions/submit.js @@ -0,0 +1,27 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.updateOperation = exports.updateDecimal = exports.toggleIsIntensity = exports.toggleIsAscend = void 0; +var _action_type = require("../constants/action_type"); +const toggleIsAscend = () => ({ + type: _action_type.SUBMIT.TOGGLE_IS_ASCEND, + payload: false +}); +exports.toggleIsAscend = toggleIsAscend; +const toggleIsIntensity = () => ({ + type: _action_type.SUBMIT.TOGGLE_IS_INTENSITY, + payload: false +}); +exports.toggleIsIntensity = toggleIsIntensity; +const updateOperation = payload => ({ + type: _action_type.SUBMIT.UPDATE_OPERATION, + payload +}); +exports.updateOperation = updateOperation; +const updateDecimal = payload => ({ + type: _action_type.SUBMIT.UPDATE_DECIMAL, + payload +}); +exports.updateDecimal = updateDecimal; \ No newline at end of file diff --git a/dist/actions/threshold.js b/dist/actions/threshold.js new file mode 100644 index 00000000..3feeeee2 --- /dev/null +++ b/dist/actions/threshold.js @@ -0,0 +1,32 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.updateUpperThresholdValue = exports.updateThresholdValue = exports.updateLowerThresholdValue = exports.toggleThresholdIsEdit = exports.resetThresholdValue = void 0; +var _action_type = require("../constants/action_type"); +const updateThresholdValue = payload => ({ + type: _action_type.THRESHOLD.UPDATE_VALUE, + payload +}); +exports.updateThresholdValue = updateThresholdValue; +const resetThresholdValue = () => ({ + type: _action_type.THRESHOLD.RESET_VALUE, + payload: false +}); +exports.resetThresholdValue = resetThresholdValue; +const toggleThresholdIsEdit = payload => ({ + type: _action_type.THRESHOLD.TOGGLE_ISEDIT, + payload +}); +exports.toggleThresholdIsEdit = toggleThresholdIsEdit; +const updateUpperThresholdValue = payload => ({ + type: _action_type.THRESHOLD.UPDATE_UPPER_VALUE, + payload +}); +exports.updateUpperThresholdValue = updateUpperThresholdValue; +const updateLowerThresholdValue = payload => ({ + type: _action_type.THRESHOLD.UPDATE_LOWER_VALUE, + payload +}); +exports.updateLowerThresholdValue = updateLowerThresholdValue; \ No newline at end of file diff --git a/dist/actions/ui.js b/dist/actions/ui.js new file mode 100644 index 00000000..26a8fcbf --- /dev/null +++ b/dist/actions/ui.js @@ -0,0 +1,43 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.setUiViewerType = exports.setUiSweepType = exports.selectUiSweep = exports.scrollUiWheel = exports.clickUiTarget = void 0; +var _action_type = require("../constants/action_type"); +const setUiViewerType = payload => ({ + type: _action_type.UI.VIEWER.SET_TYPE, + payload +}); +exports.setUiViewerType = setUiViewerType; +const setUiSweepType = exports.setUiSweepType = function setUiSweepType(payload) { + let jcampIdx = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; + return { + type: _action_type.UI.SWEEP.SET_TYPE, + payload, + jcampIdx + }; +}; +const selectUiSweep = payload => ({ + type: _action_type.UI.SWEEP.SELECT, + payload +}); +exports.selectUiSweep = selectUiSweep; +const scrollUiWheel = payload => ({ + type: _action_type.UI.WHEEL.SCROLL, + payload +}); +exports.scrollUiWheel = scrollUiWheel; +const clickUiTarget = exports.clickUiTarget = function clickUiTarget(payload, onPeak) { + let voltammetryPeakIdx = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0; + let jcampIdx = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 0; + let onPecker = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false; + return { + type: _action_type.UI.CLICK_TARGET, + payload, + onPeak, + voltammetryPeakIdx, + jcampIdx, + onPecker + }; +}; \ No newline at end of file diff --git a/dist/actions/wavelength.js b/dist/actions/wavelength.js new file mode 100644 index 00000000..e8008550 --- /dev/null +++ b/dist/actions/wavelength.js @@ -0,0 +1,14 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.updateWaveLength = void 0; +var _action_type = require("../constants/action_type"); +const updateWaveLength = payload => ({ + type: _action_type.XRD.UPDATE_WAVE_LENGTH, + payload +}); + +// eslint-disable-line +exports.updateWaveLength = updateWaveLength; \ No newline at end of file diff --git a/dist/app.js b/dist/app.js new file mode 100644 index 00000000..e2e07426 --- /dev/null +++ b/dist/app.js @@ -0,0 +1,133 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); +Object.defineProperty(exports, "__esModule", { + value: true +}); +Object.defineProperty(exports, "FN", { + enumerable: true, + get: function get() { + return _fn.default; + } +}); +exports.SpectraEditor = void 0; +var _react = _interopRequireDefault(require("react")); +var _reactRedux = require("react-redux"); +var _redux = require("redux"); +var _propTypes = _interopRequireDefault(require("prop-types")); +var _material = require("@mui/material"); +require("regenerator-runtime/runtime"); +var _reduxSaga = _interopRequireDefault(require("redux-saga")); +var _index = _interopRequireDefault(require("./reducers/index")); +var _index2 = _interopRequireDefault(require("./sagas/index")); +var _layer_init = _interopRequireDefault(require("./layer_init")); +var _fn = _interopRequireDefault(require("./fn")); +var _jsxRuntime = require("react/jsx-runtime"); +/* eslint-disable react/function-component-definition, react/require-default-props */ + +// eslint-disable-line + +// import { logger } from 'redux-logger'; + +// - - - store & middleware - - - +const sagaMiddleware = (0, _reduxSaga.default)(); +const middlewares = [sagaMiddleware]; // logger + +const store = (0, _redux.compose)((0, _redux.applyMiddleware)(...middlewares))(_redux.createStore)(_index.default); +sagaMiddleware.run(_index2.default); + +// - - - helper - - - +const ensureQuillDelta = descs => { + const isArr = Array.isArray(descs); + return isArr ? descs : [{ + insert: descs + }]; +}; + +// - - - React - - - +const SpectraEditor = _ref => { + let { + entity, + others, + cLabel, + xLabel, + yLabel, + operations, + forecast, + molSvg, + editorOnly, + descriptions, + exactMass, + canChangeDescription, + onDescriptionChanged, + multiEntities, + multiMolSvgs, + entityFileNames, + userManualLink + } = _ref; + return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactRedux.Provider, { + store: store, + children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.StyledEngineProvider, { + injectFirst: true, + children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_layer_init.default, { + entity: entity, + multiEntities: multiEntities, + entityFileNames: entityFileNames, + userManualLink: userManualLink, + others: others, + cLabel: cLabel, + xLabel: xLabel, + yLabel: yLabel, + forecast: forecast, + operations: operations, + descriptions: ensureQuillDelta(descriptions), + molSvg: molSvg, + multiMolSvgs: multiMolSvgs, + editorOnly: editorOnly, + exactMass: exactMass, + canChangeDescription: canChangeDescription, + onDescriptionChanged: onDescriptionChanged + }) + }) + }); +}; +exports.SpectraEditor = SpectraEditor; +SpectraEditor.propTypes = { + entity: _propTypes.default.object.isRequired, + multiEntities: _propTypes.default.array, + entityFileNames: _propTypes.default.array, + others: _propTypes.default.object, + cLabel: _propTypes.default.string, + xLabel: _propTypes.default.string, + yLabel: _propTypes.default.string, + forecast: _propTypes.default.object, + operations: _propTypes.default.array, + descriptions: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.array]), + molSvg: _propTypes.default.string, + multiMolSvgs: _propTypes.default.array, + editorOnly: _propTypes.default.bool, + canChangeDescription: _propTypes.default.bool, + onDescriptionChanged: _propTypes.default.func, + userManualLink: _propTypes.default.object, + exactMass: _propTypes.default.string +}; +SpectraEditor.defaultProps = { + others: { + others: [], + addOthersCb: false + }, + multiEntities: false, + entityFileNames: false, + cLabel: '', + xLabel: '', + yLabel: '', + forecast: {}, + operations: [], + descriptions: [], + molSvg: '', + exactMass: '', + multiMolSvgs: [], + editorOnly: false, + canChangeDescription: false, + userManualLink: {} +}; \ No newline at end of file diff --git a/dist/components/cmd_bar/01_viewer.js b/dist/components/cmd_bar/01_viewer.js new file mode 100644 index 00000000..00503b7d --- /dev/null +++ b/dist/components/cmd_bar/01_viewer.js @@ -0,0 +1,87 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; +var _react = _interopRequireDefault(require("react")); +var _reactRedux = require("react-redux"); +var _redux = require("redux"); +var _classnames = _interopRequireDefault(require("classnames")); +var _propTypes = _interopRequireDefault(require("prop-types")); +var _withStyles = _interopRequireDefault(require("@mui/styles/withStyles")); +var _SpellcheckOutlined = _interopRequireDefault(require("@mui/icons-material/SpellcheckOutlined")); +var _TimelineOutlined = _interopRequireDefault(require("@mui/icons-material/TimelineOutlined")); +var _Tooltip = _interopRequireDefault(require("@mui/material/Tooltip")); +var _ui = require("../../actions/ui"); +var _cfg = _interopRequireDefault(require("../../helpers/cfg")); +var _format = _interopRequireDefault(require("../../helpers/format")); +var _common = require("./common"); +var _list_ui = require("../../constants/list_ui"); +var _jsxRuntime = require("react/jsx-runtime"); +/* eslint-disable prefer-object-spread, react/function-component-definition */ + +const styles = () => Object.assign({}, _common.commonStyle); +const Viewer = _ref => { + let { + classes, + isfocusSpectrumSt, + isfocusAnalysisSt, + hideCmdAnaViewerSt, + disableCmdAnaViewerSt, + setUiViewerTypeAct + } = _ref; + const onViewSpectrum = () => setUiViewerTypeAct(_list_ui.LIST_UI_VIEWER_TYPE.SPECTRUM); + const onViewAnalysis = () => setUiViewerTypeAct(_list_ui.LIST_UI_VIEWER_TYPE.ANALYSIS); + return /*#__PURE__*/(0, _jsxRuntime.jsxs)("span", { + className: classes.group, + "data-testid": "Viewer", + children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_Tooltip.default, { + title: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: "txt-sv-tp", + children: "Spectrum Viewer" + }), + children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_common.MuButton, { + className: (0, _classnames.default)((0, _common.focusStyle)(isfocusSpectrumSt, classes), 'btn-sv-bar-spctrum'), + onClick: onViewSpectrum, + children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_TimelineOutlined.default, { + className: classes.icon + }) + }) + }), hideCmdAnaViewerSt ? null : /*#__PURE__*/(0, _jsxRuntime.jsx)(_Tooltip.default, { + title: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: "txt-sv-tp", + children: "Analysis Viewer" + }), + children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_common.MuButton, { + className: (0, _classnames.default)((0, _common.focusStyle)(isfocusAnalysisSt, classes), 'btn-sv-bar-analysis'), + disabled: disableCmdAnaViewerSt, + onClick: onViewAnalysis, + children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_SpellcheckOutlined.default, { + className: classes.icon + }) + }) + })] + }); +}; +const mapStateToProps = (state, props) => ( +// eslint-disable-line +{ + isfocusSpectrumSt: state.ui.viewer === _list_ui.LIST_UI_VIEWER_TYPE.SPECTRUM, + isfocusAnalysisSt: state.ui.viewer === _list_ui.LIST_UI_VIEWER_TYPE.ANALYSIS, + hideCmdAnaViewerSt: _cfg.default.hideCmdAnaViewer(state.layout) || props.editorOnly && !(_format.default.isNmrLayout(state.layout) || _format.default.isIrLayout(state.layout)), + disableCmdAnaViewerSt: _cfg.default.btnCmdAnaViewer(state.layout) +}); +const mapDispatchToProps = dispatch => (0, _redux.bindActionCreators)({ + setUiViewerTypeAct: _ui.setUiViewerType +}, dispatch); +Viewer.propTypes = { + classes: _propTypes.default.object.isRequired, + isfocusSpectrumSt: _propTypes.default.bool.isRequired, + isfocusAnalysisSt: _propTypes.default.bool.isRequired, + hideCmdAnaViewerSt: _propTypes.default.bool.isRequired, + disableCmdAnaViewerSt: _propTypes.default.bool.isRequired, + setUiViewerTypeAct: _propTypes.default.func.isRequired +}; +var _default = exports.default = (0, _redux.compose)((0, _reactRedux.connect)(mapStateToProps, mapDispatchToProps), (0, _withStyles.default)(styles))(Viewer); \ No newline at end of file diff --git a/dist/components/cmd_bar/02_zoom.js b/dist/components/cmd_bar/02_zoom.js new file mode 100644 index 00000000..7b7ec112 --- /dev/null +++ b/dist/components/cmd_bar/02_zoom.js @@ -0,0 +1,79 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; +var _react = _interopRequireDefault(require("react")); +var _reactRedux = require("react-redux"); +var _redux = require("redux"); +var _classnames = _interopRequireDefault(require("classnames")); +var _propTypes = _interopRequireDefault(require("prop-types")); +var _withStyles = _interopRequireDefault(require("@mui/styles/withStyles")); +var _ZoomInOutlined = _interopRequireDefault(require("@mui/icons-material/ZoomInOutlined")); +var _FindReplaceOutlined = _interopRequireDefault(require("@mui/icons-material/FindReplaceOutlined")); +var _Tooltip = _interopRequireDefault(require("@mui/material/Tooltip")); +var _ui = require("../../actions/ui"); +var _common = require("./common"); +var _list_ui = require("../../constants/list_ui"); +var _jsxRuntime = require("react/jsx-runtime"); +/* eslint-disable prefer-object-spread, react/function-component-definition */ + +const styles = () => Object.assign({}, _common.commonStyle); +const Zoom = _ref => { + let { + classes, + isfocusZoomSt, + setUiSweepTypeAct + } = _ref; + const onSweepZoomIn = () => setUiSweepTypeAct(_list_ui.LIST_UI_SWEEP_TYPE.ZOOMIN); + const onSweepZoomReset = () => setUiSweepTypeAct(_list_ui.LIST_UI_SWEEP_TYPE.ZOOMRESET); + return /*#__PURE__*/(0, _jsxRuntime.jsxs)("span", { + className: classes.group, + "data-testid": "Zoom", + children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_Tooltip.default, { + title: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: "txt-sv-tp", + children: "Zoom In" + }), + children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_common.MuButton, { + className: (0, _classnames.default)((0, _common.focusStyle)(isfocusZoomSt, classes), 'btn-sv-bar-zoomin'), + onClick: onSweepZoomIn, + children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_ZoomInOutlined.default, { + className: (0, _classnames.default)(classes.icon, classes.iconWp) + }) + }) + }) + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_Tooltip.default, { + title: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: "txt-sv-tp", + children: "Reset Zoom" + }), + children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_common.MuButton, { + className: (0, _classnames.default)('btn-sv-bar-zoomreset'), + onClick: onSweepZoomReset, + children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_FindReplaceOutlined.default, { + className: classes.icon + }) + }) + }) + })] + }); +}; +const mapStateToProps = (state, _) => ( +// eslint-disable-line +{ + isfocusZoomSt: state.ui.sweepType === _list_ui.LIST_UI_SWEEP_TYPE.ZOOMIN +}); +const mapDispatchToProps = dispatch => (0, _redux.bindActionCreators)({ + setUiSweepTypeAct: _ui.setUiSweepType +}, dispatch); +Zoom.propTypes = { + classes: _propTypes.default.object.isRequired, + isfocusZoomSt: _propTypes.default.bool.isRequired, + setUiSweepTypeAct: _propTypes.default.func.isRequired +}; +var _default = exports.default = (0, _redux.compose)((0, _reactRedux.connect)(mapStateToProps, mapDispatchToProps), (0, _withStyles.default)(styles))(Zoom); \ No newline at end of file diff --git a/dist/components/cmd_bar/03_peak.js b/dist/components/cmd_bar/03_peak.js new file mode 100644 index 00000000..b7ef0f9a --- /dev/null +++ b/dist/components/cmd_bar/03_peak.js @@ -0,0 +1,187 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; +var _react = _interopRequireDefault(require("react")); +var _reactRedux = require("react-redux"); +var _redux = require("redux"); +var _classnames = _interopRequireDefault(require("classnames")); +var _propTypes = _interopRequireDefault(require("prop-types")); +var _withStyles = _interopRequireDefault(require("@mui/styles/withStyles")); +var _Tooltip = _interopRequireDefault(require("@mui/material/Tooltip")); +var _AddLocationOutlined = _interopRequireDefault(require("@mui/icons-material/AddLocationOutlined")); +var _ui = require("../../actions/ui"); +var _cfg = _interopRequireDefault(require("../../helpers/cfg")); +var _common = require("./common"); +var _list_ui = require("../../constants/list_ui"); +var _tri_btn = _interopRequireDefault(require("./tri_btn")); +var _edit_peak = require("../../actions/edit_peak"); +var _extractPeaksEdit = require("../../helpers/extractPeaksEdit"); +var _jsxRuntime = require("react/jsx-runtime"); +/* eslint-disable prefer-object-spread, function-paren-newline, no-unused-vars, +react/function-component-definition, react/require-default-props, max-len, +react/no-unused-prop-types */ + +const styles = () => Object.assign({}, _common.commonStyle); +const Peak = _ref => { + let { + classes, + setUiSweepTypeAct, + isFocusAddPeakSt, + disableAddPeakSt, + isFocusRmPeakSt, + disableRmPeakSt, + isFocusSetRefSt, + disableSetRefSt, + isHandleMaxAndMinPeaksSt, + cyclicVotaSt, + curveSt, + clearAllPeaksAct, + feature, + editPeakSt, + thresSt, + shiftSt, + layoutSt + } = _ref; + let onSweepPeakAdd = () => setUiSweepTypeAct(_list_ui.LIST_UI_SWEEP_TYPE.PEAK_ADD); + let onSweepPeakDELETE = () => setUiSweepTypeAct(_list_ui.LIST_UI_SWEEP_TYPE.PEAK_DELETE); + let onSweepAnchorShift = () => setUiSweepTypeAct(_list_ui.LIST_UI_SWEEP_TYPE.ANCHOR_SHIFT); + const { + curveIdx + } = curveSt; + const onClearAll = () => { + const dataPeaks = (0, _extractPeaksEdit.extractAutoPeaks)(feature, thresSt, shiftSt, layoutSt); + clearAllPeaksAct({ + curveIdx, + dataPeaks + }); + }; + if (isHandleMaxAndMinPeaksSt) { + const { + spectraList + } = cyclicVotaSt; + const spectra = spectraList[curveIdx]; + if (spectra) { + const { + isWorkMaxPeak + } = spectra; + if (isWorkMaxPeak) { + onSweepPeakAdd = () => setUiSweepTypeAct(_list_ui.LIST_UI_SWEEP_TYPE.CYCLIC_VOLTA_ADD_MAX_PEAK, curveIdx); + onSweepPeakDELETE = () => setUiSweepTypeAct(_list_ui.LIST_UI_SWEEP_TYPE.CYCLIC_VOLTA_RM_MAX_PEAK, curveIdx); + } else { + onSweepPeakAdd = () => setUiSweepTypeAct(_list_ui.LIST_UI_SWEEP_TYPE.CYCLIC_VOLTA_ADD_MIN_PEAK, curveIdx); + onSweepPeakDELETE = () => setUiSweepTypeAct(_list_ui.LIST_UI_SWEEP_TYPE.CYCLIC_VOLTA_RM_MIN_PEAK, curveIdx); + } + onSweepAnchorShift = () => setUiSweepTypeAct(_list_ui.LIST_UI_SWEEP_TYPE.CYCLIC_VOLTA_SET_REF, curveIdx); + } + } + return /*#__PURE__*/(0, _jsxRuntime.jsxs)("span", { + className: classes.group, + "data-testid": "Peak", + children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_Tooltip.default, { + title: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: "txt-sv-tp", + children: "Add Peak" + }), + children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_common.MuButton, { + className: (0, _classnames.default)((0, _common.focusStyle)(isFocusAddPeakSt, classes), 'btn-sv-bar-addpeak'), + disabled: disableAddPeakSt, + onClick: onSweepPeakAdd, + children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: (0, _classnames.default)(classes.txt, 'txt-sv-bar-addpeak'), + children: "P+" + }) + }) + }) + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_Tooltip.default, { + title: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: "txt-sv-tp", + children: "Remove Peak" + }), + children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_common.MuButton, { + className: (0, _classnames.default)((0, _common.focusStyle)(isFocusRmPeakSt, classes), 'btn-sv-bar-rmpeak'), + disabled: disableRmPeakSt, + onClick: onSweepPeakDELETE, + children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: (0, _classnames.default)(classes.txt, 'txt-sv-bar-rmpeak'), + children: "P-" + }) + }) + }) + }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_tri_btn.default, { + content: { + tp: 'Clear All Peaks' + }, + cb: onClearAll, + isClearAllDisabled: disableRmPeakSt, + children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: (0, _classnames.default)(classes.txt, 'txt-sv-bar-rmallpeaks'), + children: "P" + }), /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: (0, _classnames.default)(classes.txt, classes.txtIcon, 'txt-sv-bar-rmallpeaks'), + children: "x" + })] + }), !disableSetRefSt ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_Tooltip.default, { + title: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: "txt-sv-tp", + children: "Set Reference" + }), + children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_common.MuButton, { + className: (0, _classnames.default)((0, _common.focusStyle)(isFocusSetRefSt, classes), 'btn-sv-bar-setref'), + disabled: disableSetRefSt, + onClick: onSweepAnchorShift, + children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_AddLocationOutlined.default, { + className: classes.icon + }) + }) + }) + }) : null] + }); +}; +const mapStateToProps = (state, props) => ( +// eslint-disable-line +{ + isFocusAddPeakSt: state.ui.sweepType === _list_ui.LIST_UI_SWEEP_TYPE.PEAK_ADD || state.ui.sweepType === _list_ui.LIST_UI_SWEEP_TYPE.CYCLIC_VOLTA_ADD_MAX_PEAK || state.ui.sweepType === _list_ui.LIST_UI_SWEEP_TYPE.CYCLIC_VOLTA_ADD_MIN_PEAK, + disableAddPeakSt: _cfg.default.btnCmdAddPeak(state.layout), + isFocusRmPeakSt: state.ui.sweepType === _list_ui.LIST_UI_SWEEP_TYPE.PEAK_DELETE || state.ui.sweepType === _list_ui.LIST_UI_SWEEP_TYPE.CYCLIC_VOLTA_RM_MAX_PEAK || state.ui.sweepType === _list_ui.LIST_UI_SWEEP_TYPE.CYCLIC_VOLTA_RM_MIN_PEAK, + disableRmPeakSt: _cfg.default.btnCmdRmPeak(state.layout), + isFocusSetRefSt: state.ui.sweepType === _list_ui.LIST_UI_SWEEP_TYPE.ANCHOR_SHIFT || state.ui.sweepType === _list_ui.LIST_UI_SWEEP_TYPE.CYCLIC_VOLTA_SET_REF, + disableSetRefSt: _cfg.default.btnCmdSetRef(state.layout), + isHandleMaxAndMinPeaksSt: !_cfg.default.hidePanelCyclicVolta(state.layout), + cyclicVotaSt: state.cyclicvolta, + curveSt: state.curve, + editPeakSt: state.editPeak.present, + thresSt: state.threshold.list[state.curve.curveIdx], + layoutSt: state.layout, + shiftSt: state.shift +}); +const mapDispatchToProps = dispatch => (0, _redux.bindActionCreators)({ + setUiSweepTypeAct: _ui.setUiSweepType, + clearAllPeaksAct: _edit_peak.clearAllPeaks +}, dispatch); +Peak.propTypes = { + classes: _propTypes.default.object.isRequired, + isFocusAddPeakSt: _propTypes.default.bool.isRequired, + disableAddPeakSt: _propTypes.default.bool.isRequired, + isFocusRmPeakSt: _propTypes.default.bool.isRequired, + disableRmPeakSt: _propTypes.default.bool.isRequired, + isFocusSetRefSt: _propTypes.default.bool.isRequired, + disableSetRefSt: _propTypes.default.bool.isRequired, + setUiSweepTypeAct: _propTypes.default.func.isRequired, + isHandleMaxAndMinPeaksSt: _propTypes.default.bool.isRequired, + cyclicVotaSt: _propTypes.default.object.isRequired, + curveSt: _propTypes.default.object.isRequired, + clearAllPeaksAct: _propTypes.default.func.isRequired, + feature: _propTypes.default.object.isRequired, + editPeakSt: _propTypes.default.object.isRequired, + thresSt: _propTypes.default.object.isRequired, + layoutSt: _propTypes.default.string.isRequired, + shiftSt: _propTypes.default.object.isRequired +}; +var _default = exports.default = (0, _redux.compose)((0, _reactRedux.connect)(mapStateToProps, mapDispatchToProps), (0, _withStyles.default)(styles))(Peak); \ No newline at end of file diff --git a/dist/components/cmd_bar/04_integration.js b/dist/components/cmd_bar/04_integration.js new file mode 100644 index 00000000..e751515a --- /dev/null +++ b/dist/components/cmd_bar/04_integration.js @@ -0,0 +1,213 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; +var _react = _interopRequireDefault(require("react")); +var _reactRedux = require("react-redux"); +var _redux = require("redux"); +var _classnames = _interopRequireDefault(require("classnames")); +var _propTypes = _interopRequireDefault(require("prop-types")); +var _withStyles = _interopRequireDefault(require("@mui/styles/withStyles")); +var _Tooltip = _interopRequireDefault(require("@mui/material/Tooltip")); +var _TextField = _interopRequireDefault(require("@mui/material/TextField")); +var _react2 = _interopRequireDefault(require("@mdi/react")); +var _js = require("@mdi/js"); +var _integration = require("../../actions/integration"); +var _ui = require("../../actions/ui"); +var _list_ui = require("../../constants/list_ui"); +var _cfg = _interopRequireDefault(require("../../helpers/cfg")); +var _tri_btn = _interopRequireDefault(require("./tri_btn")); +var _common = require("./common"); +var _format = _interopRequireDefault(require("../../helpers/format")); +var _jsxRuntime = require("react/jsx-runtime"); +/* eslint-disable prefer-object-spread, function-paren-newline, +react/function-component-definition, react/require-default-props, max-len, +react/no-unused-prop-types */ + +const styles = () => Object.assign({ + field: { + width: 80 + }, + txtIcon: {} +}, _common.commonStyle); +const iconSize = '16px'; +const setFactor = (classes, isDisable, integrationSt, setIntegrationFkrAct, curveIdx) => { + const onFactorChanged = e => { + e.target.blur(); + setIntegrationFkrAct({ + factor: e.target.value, + curveIdx + }); + }; + const onEnterPress = e => { + if (e.key === 'Enter') { + setIntegrationFkrAct({ + factor: e.target.value, + curveIdx + }); + } + }; + let refFactor = 1.00; + const { + integrations + } = integrationSt; + if (integrations && curveIdx < integrations.length) { + const selectedIntegration = integrations[curveIdx]; + refFactor = selectedIntegration.refFactor || 1.00; + } + return /*#__PURE__*/(0, _jsxRuntime.jsx)(_TextField.default, { + className: classes.field, + disabled: isDisable, + id: "intg-factor-name", + type: "number", + value: refFactor, + margin: "none", + InputProps: { + className: (0, _classnames.default)(classes.txtInput, 'txtfield-sv-bar-input') + }, + label: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: (0, _classnames.default)(classes.txtLabel, 'txtfield-sv-bar-label'), + children: "Ref Area" + }), + onChange: onFactorChanged, + onBlur: onFactorChanged, + onKeyUp: onEnterPress, + variant: "outlined" + }); +}; +const iconColor = criteria => criteria ? '#fff' : '#000'; +const Integration = _ref => { + let { + classes, + ignoreRef, + isDisableSt, + isFocusAddIntgSt, + isFocusRmIntgSt, + isFocusSetRefSt, + setUiSweepTypeAct, + setIntegrationFkrAct, + clearIntegrationAllAct, + curveSt, + integrationSt + } = _ref; + const onSweepIntegtAdd = () => setUiSweepTypeAct(_list_ui.LIST_UI_SWEEP_TYPE.INTEGRATION_ADD); + const onSweepIntegtRm = () => setUiSweepTypeAct(_list_ui.LIST_UI_SWEEP_TYPE.INTEGRATION_RM); + const onSweepIntegtSR = () => setUiSweepTypeAct(_list_ui.LIST_UI_SWEEP_TYPE.INTEGRATION_SET_REF); + const { + curveIdx + } = curveSt; + const onClearAll = () => clearIntegrationAllAct({ + curveIdx + }); + return /*#__PURE__*/(0, _jsxRuntime.jsxs)("span", { + className: classes.group, + children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_Tooltip.default, { + title: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: "txt-sv-tp", + children: "Add Integration" + }), + children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_common.MuButton, { + className: (0, _classnames.default)((0, _common.focusStyle)(isFocusAddIntgSt, classes), 'btn-add-inter'), + disabled: isDisableSt, + onClick: onSweepIntegtAdd, + children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_react2.default, { + path: _js.mdiMathIntegral, + size: iconSize, + color: iconColor(isFocusAddIntgSt || isDisableSt), + className: (0, _classnames.default)(classes.iconMdi, 'icon-sv-bar-addint') + }), /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: (0, _classnames.default)(classes.txt, classes.txtIcon, 'txt-sv-bar-addint'), + children: "+" + })] + }) + }) + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_Tooltip.default, { + title: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: "txt-sv-tp", + children: "Remove Integration" + }), + children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_common.MuButton, { + className: (0, _classnames.default)((0, _common.focusStyle)(isFocusRmIntgSt, classes), 'btn-remove-inter'), + disabled: isDisableSt, + onClick: onSweepIntegtRm, + children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_react2.default, { + path: _js.mdiMathIntegral, + size: iconSize, + color: iconColor(isFocusRmIntgSt || isDisableSt), + className: (0, _classnames.default)(classes.iconMdi, 'icon-sv-bar-rmint') + }), /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: (0, _classnames.default)(classes.txt, classes.txtIcon, 'txt-sv-bar-rmint'), + children: "-" + })] + }) + }) + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_Tooltip.default, { + title: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: "txt-sv-tp", + children: "Set Integration Reference" + }), + children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_common.MuButton, { + className: (0, _classnames.default)((0, _common.focusStyle)(isFocusSetRefSt, classes), 'btn-set-inter-ref'), + disabled: isDisableSt, + onClick: onSweepIntegtSR, + children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_react2.default, { + path: _js.mdiReflectVertical, + size: iconSize, + color: iconColor(isFocusSetRefSt || isDisableSt), + className: (0, _classnames.default)(classes.iconMdi, 'icon-sv-bar-refint') + }) + }) + }) + }), !ignoreRef ? setFactor(classes, isDisableSt, integrationSt, setIntegrationFkrAct, curveIdx) : null, /*#__PURE__*/(0, _jsxRuntime.jsxs)(_tri_btn.default, { + content: { + tp: 'Clear All Integration' + }, + cb: onClearAll, + children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_react2.default, { + path: _js.mdiMathIntegral, + size: iconSize, + color: iconColor(isDisableSt), + className: (0, _classnames.default)(classes.iconMdi, 'icon-sv-bar-rmallint') + }), /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: (0, _classnames.default)(classes.txt, classes.txtIcon, 'txt-sv-bar-rmallint'), + children: "x" + })] + })] + }); +}; +const mapStateToProps = (state, props) => ( +// eslint-disable-line +{ + isDisableSt: _cfg.default.btnCmdIntg(state.layout), + isFocusAddIntgSt: state.ui.sweepType === _list_ui.LIST_UI_SWEEP_TYPE.INTEGRATION_ADD, + isFocusRmIntgSt: state.ui.sweepType === _list_ui.LIST_UI_SWEEP_TYPE.INTEGRATION_RM, + isFocusSetRefSt: state.ui.sweepType === _list_ui.LIST_UI_SWEEP_TYPE.INTEGRATION_SET_REF, + ignoreRef: _format.default.isHplcUvVisLayout(state.layout), + curveSt: state.curve, + integrationSt: state.integration.present +}); +const mapDispatchToProps = dispatch => (0, _redux.bindActionCreators)({ + setUiSweepTypeAct: _ui.setUiSweepType, + setIntegrationFkrAct: _integration.setIntegrationFkr, + clearIntegrationAllAct: _integration.clearIntegrationAll +}, dispatch); +Integration.propTypes = { + classes: _propTypes.default.object.isRequired, + isDisableSt: _propTypes.default.bool.isRequired, + isFocusAddIntgSt: _propTypes.default.bool.isRequired, + isFocusRmIntgSt: _propTypes.default.bool.isRequired, + isFocusSetRefSt: _propTypes.default.bool.isRequired, + ignoreRef: _propTypes.default.bool.isRequired, + setUiSweepTypeAct: _propTypes.default.func.isRequired, + setIntegrationFkrAct: _propTypes.default.func.isRequired, + clearIntegrationAllAct: _propTypes.default.func.isRequired, + curveSt: _propTypes.default.object.isRequired, + integrationSt: _propTypes.default.object.isRequired +}; +var _default = exports.default = (0, _reactRedux.connect)(mapStateToProps, mapDispatchToProps)((0, _withStyles.default)(styles)(Integration)); \ No newline at end of file diff --git a/dist/components/cmd_bar/05_multiplicity.js b/dist/components/cmd_bar/05_multiplicity.js new file mode 100644 index 00000000..b11121af --- /dev/null +++ b/dist/components/cmd_bar/05_multiplicity.js @@ -0,0 +1,161 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; +var _react = _interopRequireDefault(require("react")); +var _reactRedux = require("react-redux"); +var _redux = require("redux"); +var _classnames = _interopRequireDefault(require("classnames")); +var _propTypes = _interopRequireDefault(require("prop-types")); +var _withStyles = _interopRequireDefault(require("@mui/styles/withStyles")); +var _Tooltip = _interopRequireDefault(require("@mui/material/Tooltip")); +var _ui = require("../../actions/ui"); +var _multiplicity = require("../../actions/multiplicity"); +var _list_ui = require("../../constants/list_ui"); +var _cfg = _interopRequireDefault(require("../../helpers/cfg")); +var _tri_btn = _interopRequireDefault(require("./tri_btn")); +var _common = require("./common"); +var _jsxRuntime = require("react/jsx-runtime"); +/* eslint-disable prefer-object-spread, function-paren-newline, +react/function-component-definition, react/require-default-props, max-len, +react/no-unused-prop-types */ + +const styles = () => Object.assign({}, _common.commonStyle); +const Multiplicity = _ref => { + let { + classes, + isFocusAddMpySt, + disableAddMpySt, + isFocusRmMpySt, + disableRmMpySt, + isFocusAddPeakSt, + isFocusRmPeakSt, + disableMpyPeakSt, + setUiSweepTypeAct, + clearMpyAllAct, + curveSt + } = _ref; + const onSweepMutAdd = () => setUiSweepTypeAct(_list_ui.LIST_UI_SWEEP_TYPE.MULTIPLICITY_SWEEP_ADD); + const onOneMutAdd = () => setUiSweepTypeAct(_list_ui.LIST_UI_SWEEP_TYPE.MULTIPLICITY_ONE_RM); + const onPeakMutAdd = () => setUiSweepTypeAct(_list_ui.LIST_UI_SWEEP_TYPE.MULTIPLICITY_PEAK_ADD); + const onPeakMutRm = () => setUiSweepTypeAct(_list_ui.LIST_UI_SWEEP_TYPE.MULTIPLICITY_PEAK_RM); + const { + curveIdx + } = curveSt; + const onClearAll = () => clearMpyAllAct({ + curveIdx + }); + return /*#__PURE__*/(0, _jsxRuntime.jsxs)("span", { + className: classes.group, + children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_Tooltip.default, { + title: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: "txt-sv-tp", + children: "Add Multiplicity" + }), + children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_common.MuButton, { + className: (0, _classnames.default)((0, _common.focusStyle)(isFocusAddMpySt, classes), 'btn-sv-bar-addmpy'), + disabled: disableAddMpySt, + onClick: onSweepMutAdd, + children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: (0, _classnames.default)(classes.txt, 'txt-sv-bar-addmpy'), + children: "J+" + }) + }) + }) + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_Tooltip.default, { + title: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: "txt-sv-tp", + children: "Remove Multiplicity" + }), + children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_common.MuButton, { + className: (0, _classnames.default)((0, _common.focusStyle)(isFocusRmMpySt, classes), 'btn-sv-bar-rmmpy'), + disabled: disableRmMpySt, + onClick: onOneMutAdd, + children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: (0, _classnames.default)(classes.txt, 'txt-sv-bar-rmmpy'), + children: "J-" + }) + }) + }) + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_Tooltip.default, { + title: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: "txt-sv-tp", + children: "Add Peak for Multiplicity" + }), + children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_common.MuButton, { + className: (0, _classnames.default)((0, _common.focusStyle)(isFocusAddPeakSt, classes), 'btn-sv-bar-addpeakmpy'), + disabled: disableMpyPeakSt, + onClick: onPeakMutAdd, + children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: (0, _classnames.default)(classes.txt, 'txt-sv-bar-addpeakmpy'), + children: "JP+" + }) + }) + }) + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_Tooltip.default, { + title: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: "txt-sv-tp", + children: "Remove Peak for Multiplicity" + }), + children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_common.MuButton, { + className: (0, _classnames.default)((0, _common.focusStyle)(isFocusRmPeakSt, classes), 'btn-sv-bar-rmpeakmpy'), + disabled: disableMpyPeakSt, + onClick: onPeakMutRm, + children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: (0, _classnames.default)(classes.txt, 'txt-sv-bar-rmpeakmpy'), + children: "JP-" + }) + }) + }) + }), disableAddMpySt ? null : + /*#__PURE__*/ + // eslint-disable-line + (0, _jsxRuntime.jsx)(_tri_btn.default, { + content: { + tp: 'Clear All Multiplicity' + }, + cb: onClearAll, + children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: (0, _classnames.default)(classes.txt, 'txt-sv-bar-rmallmpy'), + children: "Jx" + }) + })] + }); +}; +const mapStateToProps = (state, props) => ( +// eslint-disable-line +{ + isFocusAddMpySt: state.ui.sweepType === _list_ui.LIST_UI_SWEEP_TYPE.MULTIPLICITY_SWEEP_ADD, + disableAddMpySt: _cfg.default.btnCmdMpy(state.layout), + isFocusRmMpySt: state.ui.sweepType === _list_ui.LIST_UI_SWEEP_TYPE.MULTIPLICITY_ONE_RM, + disableRmMpySt: _cfg.default.btnCmdMpy(state.layout), + isFocusAddPeakSt: state.ui.sweepType === _list_ui.LIST_UI_SWEEP_TYPE.MULTIPLICITY_PEAK_ADD, + isFocusRmPeakSt: state.ui.sweepType === _list_ui.LIST_UI_SWEEP_TYPE.MULTIPLICITY_PEAK_RM, + disableMpyPeakSt: _cfg.default.btnCmdMpyPeak(state.layout, state.multiplicity.present, state.curve.curveIdx), + curveSt: state.curve +}); +const mapDispatchToProps = dispatch => (0, _redux.bindActionCreators)({ + setUiSweepTypeAct: _ui.setUiSweepType, + clearMpyAllAct: _multiplicity.clearMpyAll +}, dispatch); +Multiplicity.propTypes = { + classes: _propTypes.default.object.isRequired, + isFocusAddMpySt: _propTypes.default.bool.isRequired, + disableAddMpySt: _propTypes.default.bool.isRequired, + isFocusRmMpySt: _propTypes.default.bool.isRequired, + disableRmMpySt: _propTypes.default.bool.isRequired, + isFocusAddPeakSt: _propTypes.default.bool.isRequired, + isFocusRmPeakSt: _propTypes.default.bool.isRequired, + disableMpyPeakSt: _propTypes.default.bool.isRequired, + setUiSweepTypeAct: _propTypes.default.func.isRequired, + clearMpyAllAct: _propTypes.default.func.isRequired, + curveSt: _propTypes.default.object.isRequired +}; +var _default = exports.default = (0, _reactRedux.connect)(mapStateToProps, mapDispatchToProps)((0, _withStyles.default)(styles)(Multiplicity)); \ No newline at end of file diff --git a/dist/components/cmd_bar/06_undo_redo.js b/dist/components/cmd_bar/06_undo_redo.js new file mode 100644 index 00000000..05afa55f --- /dev/null +++ b/dist/components/cmd_bar/06_undo_redo.js @@ -0,0 +1,87 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; +var _react = _interopRequireDefault(require("react")); +var _reactRedux = require("react-redux"); +var _redux = require("redux"); +var _propTypes = _interopRequireDefault(require("prop-types")); +var _classnames = _interopRequireDefault(require("classnames")); +var _reduxUndo = require("redux-undo"); +var _withStyles = _interopRequireDefault(require("@mui/styles/withStyles")); +var _Tooltip = _interopRequireDefault(require("@mui/material/Tooltip")); +var _RedoOutlined = _interopRequireDefault(require("@mui/icons-material/RedoOutlined")); +var _UndoOutlined = _interopRequireDefault(require("@mui/icons-material/UndoOutlined")); +var _common = require("./common"); +var _jsxRuntime = require("react/jsx-runtime"); +/* eslint-disable prefer-object-spread, function-paren-newline, +react/function-component-definition, react/require-default-props, max-len, +react/no-unused-prop-types */ + +const styles = () => Object.assign({}, _common.commonStyle); +const UndoRedo = _ref => { + let { + classes, + canUndo, + canRedo, + onUndoAct, + onRedoAct + } = _ref; + return /*#__PURE__*/(0, _jsxRuntime.jsxs)("span", { + className: classes.group, + children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_Tooltip.default, { + title: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: "txt-sv-tp", + children: "Undo" + }), + children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_common.MuButton, { + className: (0, _classnames.default)('btn-sv-bar-undo'), + disabled: !canUndo, + onClick: onUndoAct, + children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_UndoOutlined.default, { + className: classes.icon + }) + }) + }) + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_Tooltip.default, { + title: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: "txt-sv-tp", + children: "Redo" + }), + children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_common.MuButton, { + className: (0, _classnames.default)('btn-sv-bar-redo'), + disabled: !canRedo, + onClick: onRedoAct, + children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_RedoOutlined.default, { + className: classes.icon + }) + }) + }) + })] + }); +}; +const canUndoFunc = state => state.editPeak.past.length > 0 || state.integration.past.length > 0 || state.multiplicity.past.length > 0; +const canRedoFunc = state => state.editPeak.future.length > 0 || state.integration.future.length > 0 || state.multiplicity.future.length > 0; +const mapStateToProps = (state, _) => ( +// eslint-disable-line +{ + canUndo: canUndoFunc(state), + canRedo: canRedoFunc(state) +}); +const mapDispatchToProps = dispatch => ({ + onUndoAct: () => dispatch(_reduxUndo.ActionCreators.undo()), + onRedoAct: () => dispatch(_reduxUndo.ActionCreators.redo()) +}); +UndoRedo.propTypes = { + classes: _propTypes.default.object.isRequired, + canUndo: _propTypes.default.bool.isRequired, + canRedo: _propTypes.default.bool.isRequired, + onUndoAct: _propTypes.default.func.isRequired, + onRedoAct: _propTypes.default.func.isRequired +}; +var _default = exports.default = (0, _redux.compose)((0, _reactRedux.connect)(mapStateToProps, mapDispatchToProps), (0, _withStyles.default)(styles))(UndoRedo); \ No newline at end of file diff --git a/dist/components/cmd_bar/07_pecker.js b/dist/components/cmd_bar/07_pecker.js new file mode 100644 index 00000000..4e0308d7 --- /dev/null +++ b/dist/components/cmd_bar/07_pecker.js @@ -0,0 +1,194 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; +var _react = _interopRequireDefault(require("react")); +var _reactRedux = require("react-redux"); +var _redux = require("redux"); +var _classnames = _interopRequireDefault(require("classnames")); +var _propTypes = _interopRequireDefault(require("prop-types")); +var _withStyles = _interopRequireDefault(require("@mui/styles/withStyles")); +var _Tooltip = _interopRequireDefault(require("@mui/material/Tooltip")); +var _material = require("@mui/material"); +var _AddLocationOutlined = _interopRequireDefault(require("@mui/icons-material/AddLocationOutlined")); +var _ui = require("../../actions/ui"); +var _common = require("./common"); +var _list_ui = require("../../constants/list_ui"); +var _cfg = _interopRequireDefault(require("../../helpers/cfg")); +var _cyclic_voltammetry = require("../../actions/cyclic_voltammetry"); +var _jsxRuntime = require("react/jsx-runtime"); +/* eslint-disable prefer-object-spread, function-paren-newline, +react/function-component-definition, react/require-default-props, max-len, +react/no-unused-prop-types */ + +const styles = () => Object.assign({ + field: { + width: 80 + }, + txtIcon: {} +}, _common.commonStyle); +const setRef = (classes, cyclicVotaSt, curveIdx, setCylicVoltaRefFactorAct) => { + const { + spectraList + } = cyclicVotaSt; + const spectra = spectraList[curveIdx]; + let refFactor = 0.0; + let hasRefPeaks = false; + if (spectra) { + const { + shift, + hasRefPeak + } = spectra; + const { + val + } = shift; + refFactor = val; + hasRefPeaks = hasRefPeak; + } + const onFactorChanged = e => setCylicVoltaRefFactorAct({ + factor: e.target.value, + curveIdx + }); + const onEnterPress = e => { + if (e.key === 'Enter') { + setCylicVoltaRefFactorAct({ + factor: e.target.value, + curveIdx + }); + } + }; + return /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.TextField, { + className: classes.field, + id: "intg-factor-name", + type: "number", + value: refFactor, + margin: "none", + InputProps: { + className: (0, _classnames.default)(classes.txtInput, 'txtfield-sv-bar-input') + }, + label: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: (0, _classnames.default)(classes.txtLabel, 'txtfield-sv-bar-label'), + children: hasRefPeaks ? 'Ref Value (V)' : 'Shift' + }), + variant: "outlined", + onChange: onFactorChanged, + onBlur: onFactorChanged, + onKeyUp: onEnterPress + }); +}; +const Pecker = _ref => { + let { + classes, + layoutSt, + isFocusAddPeckerSt, + isFocusRmPeckerSt, + setUiSweepTypeAct, + curveSt, + cyclicVotaSt, + setCylicVoltaRefFactorAct, + isFocusSetRefSt, + setCylicVoltaRefAct + } = _ref; + const { + curveIdx + } = curveSt; + const onSweepPeckerAdd = () => setUiSweepTypeAct(_list_ui.LIST_UI_SWEEP_TYPE.CYCLIC_VOLTA_ADD_PECKER, curveIdx); + const onSweepPeckerDELETE = () => setUiSweepTypeAct(_list_ui.LIST_UI_SWEEP_TYPE.CYCLIC_VOLTA_RM_PECKER, curveIdx); + const onConfirmSetRef = () => setCylicVoltaRefAct({ + jcampIdx: curveIdx + }); + const { + spectraList + } = cyclicVotaSt; + const spectra = spectraList[curveIdx]; + let hasRefPeaks = false; + if (spectra) { + const { + hasRefPeak + } = spectra; + hasRefPeaks = hasRefPeak; + } + return !_cfg.default.hidePanelCyclicVolta(layoutSt) ? /*#__PURE__*/(0, _jsxRuntime.jsxs)("span", { + "data-testid": "Pecker", + children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_Tooltip.default, { + title: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: "txt-sv-tp", + children: "Add Pecker" + }), + children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_common.MuButton, { + className: (0, _classnames.default)((0, _common.focusStyle)(isFocusAddPeckerSt, classes), 'btn-sv-bar-addpecker'), + onClick: onSweepPeckerAdd, + children: /*#__PURE__*/(0, _jsxRuntime.jsxs)("span", { + className: (0, _classnames.default)(classes.txt, 'txt-sv-bar-addpeak'), + children: ["I", /*#__PURE__*/(0, _jsxRuntime.jsx)("sub", { + children: "\u03BB0" + }), "+"] + }) + }) + }) + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_Tooltip.default, { + title: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: "txt-sv-tp", + children: "Remove Pecker" + }), + children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_common.MuButton, { + className: (0, _classnames.default)((0, _common.focusStyle)(isFocusRmPeckerSt, classes), 'btn-sv-bar-rmpecker'), + onClick: onSweepPeckerDELETE, + children: /*#__PURE__*/(0, _jsxRuntime.jsxs)("span", { + className: (0, _classnames.default)(classes.txt, 'txt-sv-bar-rmpeak'), + children: ["I", /*#__PURE__*/(0, _jsxRuntime.jsx)("sub", { + children: "\u03BB0" + }), "-"] + }) + }) + }) + }), setRef(classes, cyclicVotaSt, curveIdx, setCylicVoltaRefFactorAct), /*#__PURE__*/(0, _jsxRuntime.jsx)(_Tooltip.default, { + title: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: "txt-sv-tp", + children: hasRefPeaks ? 'Set Reference' : 'Set Shift' + }), + children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_common.MuButton, { + className: (0, _classnames.default)((0, _common.focusStyle)(isFocusSetRefSt, classes), 'btn-sv-bar-setref'), + onClick: onConfirmSetRef, + children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_AddLocationOutlined.default, { + className: classes.icon + }) + }) + }) + })] + }) : /*#__PURE__*/(0, _jsxRuntime.jsx)("span", {}); +}; +const mapStateToProps = (state, _) => ( +// eslint-disable-line +{ + layoutSt: state.layout, + isFocusAddPeckerSt: state.ui.sweepType === _list_ui.LIST_UI_SWEEP_TYPE.CYCLIC_VOLTA_ADD_PECKER, + isFocusRmPeckerSt: state.ui.sweepType === _list_ui.LIST_UI_SWEEP_TYPE.CYCLIC_VOLTA_RM_PECKER, + isFocusSetRefSt: state.ui.sweepType === _list_ui.LIST_UI_SWEEP_TYPE.ANCHOR_SHIFT || state.ui.sweepType === _list_ui.LIST_UI_SWEEP_TYPE.CYCLIC_VOLTA_SET_REF, + cyclicVotaSt: state.cyclicvolta, + curveSt: state.curve +}); +const mapDispatchToProps = dispatch => (0, _redux.bindActionCreators)({ + setUiSweepTypeAct: _ui.setUiSweepType, + setCylicVoltaRefFactorAct: _cyclic_voltammetry.setCylicVoltaRefFactor, + setCylicVoltaRefAct: _cyclic_voltammetry.setCylicVoltaRef +}, dispatch); +Pecker.propTypes = { + classes: _propTypes.default.object.isRequired, + layoutSt: _propTypes.default.string.isRequired, + isFocusAddPeckerSt: _propTypes.default.bool.isRequired, + isFocusRmPeckerSt: _propTypes.default.bool.isRequired, + setUiSweepTypeAct: _propTypes.default.func.isRequired, + isFocusSetRefSt: _propTypes.default.bool.isRequired, + cyclicVotaSt: _propTypes.default.object.isRequired, + curveSt: _propTypes.default.object.isRequired, + setCylicVoltaRefFactorAct: _propTypes.default.func.isRequired, + setCylicVoltaRefAct: _propTypes.default.func.isRequired +}; +var _default = exports.default = (0, _redux.compose)((0, _reactRedux.connect)(mapStateToProps, mapDispatchToProps), (0, _withStyles.default)(styles))(Pecker); \ No newline at end of file diff --git a/dist/components/cmd_bar/common.js b/dist/components/cmd_bar/common.js new file mode 100644 index 00000000..f99639f0 --- /dev/null +++ b/dist/components/cmd_bar/common.js @@ -0,0 +1,127 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.focusStyle = exports.commonStyle = exports.MuButton = void 0; +var _react = _interopRequireDefault(require("react")); +var _styles = require("@mui/styles"); +var _Button = _interopRequireDefault(require("@mui/material/Button")); +var _classnames = _interopRequireDefault(require("classnames")); +var _jsxRuntime = require("react/jsx-runtime"); +/* eslint-disable no-unused-vars, max-len, indent, react/function-component-definition, react/self-closing-comp, react/prop-types, react/jsx-props-no-spreading */ + +const useStyles = (0, _styles.makeStyles)(theme => ({ + muiBtn: { + border: '1px solid #ccc', + borderRadius: 4, + fontFamily: 'Helvetica', + fontSize: 20, + height: 30, + lineHeight: '20px', + minWidth: 30, + padding: 0, + width: 30, + color: 'black' + } +})); +const MuButton = props => { + const classes = useStyles(); + const { + className, + ...other + } = props; + return /*#__PURE__*/(0, _jsxRuntime.jsx)(_Button.default, { + className: (0, _classnames.default)(classes.muiBtn, className), + ...other + }); +}; +exports.MuButton = MuButton; +const commonStyle = exports.commonStyle = { + card: { + margin: '0 0 5px 52px', + border: '1px solid white', + borderRadius: 4 + }, + group: { + display: 'inline-block', + margin: '0px 0px 0px 10px', + verticalAlign: 'middle' + }, + groupRightMost: { + display: 'inline-block', + float: 'right', + margin: '0px 0px 0px 10px', + verticalAlign: 'middle' + }, + groupRight: { + display: 'inline-block', + float: 'right', + margin: '0px 0px 0px 10px', + verticalAlign: 'middle' + }, + btnHt: { + backgroundColor: '#2196f3', + color: '#fff', + '&:hover': { + backgroundColor: '#51c6f3' + } + }, + iconWp: { + border: '1px dashed', + borderRadius: '4px' + }, + icon: { + fontSize: 20 + }, + iconMdi: { + fontSize: 20 + }, + txt: { + fontFamily: 'Helvetica', + fontSize: 12, + fontStyle: 'italic', + fontWeight: 'bold' + }, + txtLabel: { + fontFamily: 'Helvetica', + fontSize: 12 + }, + txtInput: { + fontFamily: 'Helvetica', + fontSize: 12, + height: 30 + }, + txtOpt: { + fontFamily: 'Helvetica', + fontSize: 12 + }, + selectLabel: { + fontFamily: 'Helvetica', + fontSize: 12 + }, + selectInput: { + height: 30 + }, + txtLabelBottomInput: { + fontFamily: 'Helvetica', + backgroundColor: 'white', + fontSize: 12, + margin: '22% 0 0 7px', + padding: '0 10px 0 10px', + transform: 'scale(0.75)' + }, + txtLabelTopInput: { + fontFamily: 'Helvetica', + backgroundColor: 'white', + fontSize: 12, + margin: '-8% 0 0 7px', + padding: '0 10px 0 10px', + transform: 'scale(0.75)' + } +}; +const focusStyle = (criteria, cls) => criteria ? [cls.btnHt] : []; + +// eslint-disable-line +exports.focusStyle = focusStyle; \ No newline at end of file diff --git a/dist/components/cmd_bar/index.js b/dist/components/cmd_bar/index.js new file mode 100644 index 00000000..5826d1ed --- /dev/null +++ b/dist/components/cmd_bar/index.js @@ -0,0 +1,82 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; +var _react = _interopRequireDefault(require("react")); +var _reactRedux = require("react-redux"); +var _redux = require("redux"); +var _propTypes = _interopRequireDefault(require("prop-types")); +var _withStyles = _interopRequireDefault(require("@mui/styles/withStyles")); +var _common = require("./common"); +var _viewer = _interopRequireDefault(require("./01_viewer")); +var _zoom = _interopRequireDefault(require("./02_zoom")); +var _peak = _interopRequireDefault(require("./03_peak")); +var _integration = _interopRequireDefault(require("./04_integration")); +var _multiplicity = _interopRequireDefault(require("./05_multiplicity")); +var _undo_redo = _interopRequireDefault(require("./06_undo_redo")); +var _r01_layout = _interopRequireDefault(require("./r01_layout")); +var _r03_threshold = _interopRequireDefault(require("./r03_threshold")); +var _r04_submit = _interopRequireDefault(require("./r04_submit")); +var _r07_wavelength_btn = _interopRequireDefault(require("./r07_wavelength_btn")); +var _pecker = _interopRequireDefault(require("./07_pecker")); +var _r08_change_axes = _interopRequireDefault(require("./r08_change_axes")); +var _r09_detector = _interopRequireDefault(require("./r09_detector")); +var _jsxRuntime = require("react/jsx-runtime"); +/* eslint-disable prefer-object-spread, function-paren-newline, +react/function-component-definition, react/require-default-props */ + +const styles = () => Object.assign({}, {}, _common.commonStyle); +const CmdBar = _ref => { + let { + classes, + feature, + hasEdit, + forecast, + operations, + editorOnly, + jcampIdx, + hideThreshold + } = _ref; + return /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", { + className: classes.card, + children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_viewer.default, { + editorOnly: editorOnly + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_zoom.default, {}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_peak.default, { + jcampIdx: jcampIdx, + feature: feature + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_pecker.default, { + jcampIdx: jcampIdx + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_integration.default, {}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_multiplicity.default, {}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_undo_redo.default, {}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_r04_submit.default, { + operations: operations, + feature: feature, + forecast: forecast, + editorOnly: editorOnly, + hideSwitch: false, + disabled: false + }), hideThreshold ? null : /*#__PURE__*/(0, _jsxRuntime.jsx)(_r03_threshold.default, { + feature: feature, + hasEdit: hasEdit + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_r01_layout.default, { + feature: feature, + hasEdit: hasEdit + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_r07_wavelength_btn.default, {}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_r08_change_axes.default, {}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_r09_detector.default, {})] + }); +}; +const mapStateToProps = (state, _) => ( +// eslint-disable-line +{}); +const mapDispatchToProps = dispatch => (0, _redux.bindActionCreators)({}, dispatch); +CmdBar.propTypes = { + classes: _propTypes.default.object.isRequired, + feature: _propTypes.default.object.isRequired, + forecast: _propTypes.default.object.isRequired, + hasEdit: _propTypes.default.bool.isRequired, + operations: _propTypes.default.array.isRequired, + editorOnly: _propTypes.default.bool.isRequired, + jcampIdx: _propTypes.default.any, + hideThreshold: _propTypes.default.bool +}; +var _default = exports.default = (0, _redux.compose)((0, _reactRedux.connect)(mapStateToProps, mapDispatchToProps), (0, _withStyles.default)(styles))(CmdBar); \ No newline at end of file diff --git a/dist/components/cmd_bar/r01_layout.js b/dist/components/cmd_bar/r01_layout.js new file mode 100644 index 00000000..f4de060f --- /dev/null +++ b/dist/components/cmd_bar/r01_layout.js @@ -0,0 +1,354 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; +var _react = _interopRequireWildcard(require("react")); +var _propTypes = _interopRequireDefault(require("prop-types")); +var _classnames = _interopRequireDefault(require("classnames")); +var _reactRedux = require("react-redux"); +var _redux = require("redux"); +var _material = require("@mui/material"); +var _withStyles = _interopRequireDefault(require("@mui/styles/withStyles")); +var _r02_scan = _interopRequireDefault(require("./r02_scan")); +var _layout = require("../../actions/layout"); +var _shift = require("../../actions/shift"); +var _list_layout = require("../../constants/list_layout"); +var _list_shift = require("../../constants/list_shift"); +var _cfg = _interopRequireDefault(require("../../helpers/cfg")); +var _common = require("./common"); +var _format = _interopRequireDefault(require("../../helpers/format")); +var _jsxRuntime = require("react/jsx-runtime"); +function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); } +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; } +/* eslint-disable prefer-object-spread, function-paren-newline, +react/function-component-definition */ + +const styles = () => Object.assign({ + fieldShift: { + width: 160 + }, + fieldLayout: { + width: 100 + } +}, _common.commonStyle); +const shiftSelect = (classes, layoutSt, setShiftRefAct, shiftSt, curveSt) => { + if (_cfg.default.hideSolvent(layoutSt)) { + return null; + } + const { + curveIdx + } = curveSt; + const { + shifts + } = shiftSt; + const selectedShift = shifts[curveIdx] || {}; + const listShift = (0, _list_shift.getListShift)(layoutSt) || []; + const shiftRefName = selectedShift?.ref?.name || ''; + const isInList = listShift.some(r => r.name === shiftRefName); + const selectValue = isInList ? shiftRefName : ''; + const onChange = e => { + const name = e.target.value; + const refObj = listShift.find(r => r.name === name); + if (refObj) { + setShiftRefAct({ + dataToSet: refObj, + curveIdx + }); + } + }; + return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_material.FormControl, { + className: (0, _classnames.default)(classes.fieldShift), + variant: "outlined", + children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_material.InputLabel, { + id: "select-solvent-label", + className: (0, _classnames.default)(classes.selectLabel, 'select-sv-bar-label'), + children: "Reference" + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Select, { + value: selectValue, + labelId: "select-solvent-label", + label: "Solvent", + onChange: onChange, + className: (0, _classnames.default)(classes.selectInput, 'input-sv-bar-shift'), + children: listShift.map(ref => /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.MenuItem, { + value: ref.name, + children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: (0, _classnames.default)(classes.txtOpt, 'option-sv-bar-shift'), + children: `${ref.name}: ${_format.default.strNumberFixedDecimal(ref.value, 2)} ppm` + }) + }, ref.name)) + })] + }); +}; +const layoutSelect = (classes, layoutSt, updateLayoutAct) => { + const onChange = e => updateLayoutAct(e.target.value); + return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_material.FormControl, { + className: (0, _classnames.default)(classes.fieldLayout), + children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_material.InputLabel, { + id: "select-layout-label", + className: (0, _classnames.default)(classes.selectLabel, 'select-sv-bar-label'), + children: "Layout" + }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_material.Select, { + labelId: "select-layout-label", + label: "Layout", + value: layoutSt, + onChange: onChange, + className: (0, _classnames.default)(classes.selectInput, 'input-sv-bar-layout'), + children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_material.MenuItem, { + value: _list_layout.LIST_LAYOUT.PLAIN, + children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: (0, _classnames.default)(classes.txtOpt, 'option-sv-bar-layout'), + children: "plain" + }) + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.MenuItem, { + value: _list_layout.LIST_LAYOUT.IR, + children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: (0, _classnames.default)(classes.txtOpt, 'option-sv-bar-layout'), + children: "IR" + }) + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.MenuItem, { + value: _list_layout.LIST_LAYOUT.RAMAN, + children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: (0, _classnames.default)(classes.txtOpt, 'option-sv-bar-layout'), + children: "RAMAN" + }) + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.MenuItem, { + value: _list_layout.LIST_LAYOUT.UVVIS, + children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: (0, _classnames.default)(classes.txtOpt, 'option-sv-bar-layout'), + children: "UV/VIS" + }) + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.MenuItem, { + value: _list_layout.LIST_LAYOUT.HPLC_UVVIS, + children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: (0, _classnames.default)(classes.txtOpt, 'option-sv-bar-layout'), + children: "HPLC UV/VIS" + }) + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.MenuItem, { + value: _list_layout.LIST_LAYOUT.TGA, + children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: (0, _classnames.default)(classes.txtOpt, 'option-sv-bar-layout'), + children: "TGA (THERMOGRAVIMETRIC ANALYSIS)" + }) + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.MenuItem, { + value: _list_layout.LIST_LAYOUT.DSC, + children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: (0, _classnames.default)(classes.txtOpt, 'option-sv-bar-layout'), + children: "DSC (DIFFERENTIAL SCANNING CALORIMETRY)" + }) + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.MenuItem, { + value: _list_layout.LIST_LAYOUT.XRD, + children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: (0, _classnames.default)(classes.txtOpt, 'option-sv-bar-layout'), + children: "XRD (X-RAY DIFFRACTION)" + }) + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.MenuItem, { + value: _list_layout.LIST_LAYOUT.H1, + children: /*#__PURE__*/(0, _jsxRuntime.jsxs)("span", { + className: (0, _classnames.default)(classes.txtOpt, 'option-sv-bar-layout'), + children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("sup", { + children: "1" + }), "H"] + }) + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.MenuItem, { + value: _list_layout.LIST_LAYOUT.C13, + children: /*#__PURE__*/(0, _jsxRuntime.jsxs)("span", { + className: (0, _classnames.default)(classes.txtOpt, 'option-sv-bar-layout'), + children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("sup", { + children: "13" + }), "C"] + }) + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.MenuItem, { + value: _list_layout.LIST_LAYOUT.F19, + children: /*#__PURE__*/(0, _jsxRuntime.jsxs)("span", { + className: (0, _classnames.default)(classes.txtOpt, 'option-sv-bar-layout'), + children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("sup", { + children: "19" + }), "F"] + }) + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.MenuItem, { + value: _list_layout.LIST_LAYOUT.P31, + children: /*#__PURE__*/(0, _jsxRuntime.jsxs)("span", { + className: (0, _classnames.default)(classes.txtOpt, 'option-sv-bar-layout'), + children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("sup", { + children: "31" + }), "P"] + }) + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.MenuItem, { + value: _list_layout.LIST_LAYOUT.N15, + children: /*#__PURE__*/(0, _jsxRuntime.jsxs)("span", { + className: (0, _classnames.default)(classes.txtOpt, 'option-sv-bar-layout'), + children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("sup", { + children: "15" + }), "N"] + }) + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.MenuItem, { + value: _list_layout.LIST_LAYOUT.Si29, + children: /*#__PURE__*/(0, _jsxRuntime.jsxs)("span", { + className: (0, _classnames.default)(classes.txtOpt, 'option-sv-bar-layout'), + children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("sup", { + children: "29" + }), "Si"] + }) + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.MenuItem, { + value: _list_layout.LIST_LAYOUT.MS, + children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: (0, _classnames.default)(classes.txtOpt, 'option-sv-bar-layout'), + children: "MS" + }) + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.MenuItem, { + value: _list_layout.LIST_LAYOUT.CYCLIC_VOLTAMMETRY, + children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: (0, _classnames.default)(classes.txtOpt, 'option-sv-bar-layout'), + children: "CV (CYCLIC VOLTAMMETRY)" + }) + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.MenuItem, { + value: _list_layout.LIST_LAYOUT.CDS, + children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: (0, _classnames.default)(classes.txtOpt, 'option-sv-bar-layout'), + children: "CDS (CIRCULAR DICHROISM SPECTROSCOPY)" + }) + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.MenuItem, { + value: _list_layout.LIST_LAYOUT.SEC, + children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: (0, _classnames.default)(classes.txtOpt, 'option-sv-bar-layout'), + children: "SEC" + }) + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.MenuItem, { + value: _list_layout.LIST_LAYOUT.GC, + children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: (0, _classnames.default)(classes.txtOpt, 'option-sv-bar-layout'), + children: "GC (GAS CHROMATOGRAPHY)" + }) + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.MenuItem, { + value: _list_layout.LIST_LAYOUT.AIF, + children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: (0, _classnames.default)(classes.txtOpt, 'option-sv-bar-layout'), + children: "SORPTION-DESORPTION" + }) + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.MenuItem, { + value: _list_layout.LIST_LAYOUT.EMISSIONS, + children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: (0, _classnames.default)(classes.txtOpt, 'option-sv-bar-layout'), + children: "EMISSIONS" + }) + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.MenuItem, { + value: _list_layout.LIST_LAYOUT.DLS_ACF, + children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: (0, _classnames.default)(classes.txtOpt, 'option-sv-bar-layout'), + children: "DLS ACF" + }) + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.MenuItem, { + value: _list_layout.LIST_LAYOUT.DLS_INTENSITY, + children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: (0, _classnames.default)(classes.txtOpt, 'option-sv-bar-layout'), + children: "DLS INTENSITY" + }) + })] + })] + }); +}; +const PLACEHOLDER = '- - -'; +const norm = s => (s || '').toString().toLowerCase().normalize('NFKD').replace(/[^a-z0-9]+/g, ''); +function solventKeyOf(feature) { + const r = feature?.metadata?.solventName ?? feature?.metadata?.solvent ?? feature?.meta?.solventName ?? feature?.meta?.solvent ?? feature?.solventName ?? feature?.solvent ?? null; + const a = feature?.metadata?.solvent_label ?? feature?.metadata?.solventLabel ?? null; + const raw = r && r !== PLACEHOLDER ? r : null; + const alt = a && a !== PLACEHOLDER ? a : null; + return norm(raw || alt || ''); +} +function pickBestRef(list, key) { + if (!key || !list?.length) return null; + const scored = []; + list.forEach(r => { + const nLabel = norm(r.label); + const nName = norm(r.name); + const nNsdb = norm(r.nsdb); + let s = 0; + if (nLabel && nLabel === key) s += 3; + if (nNsdb && nNsdb.includes(key)) s += 2; + if (nName && nName.includes(key)) s += 1; + if (s > 0) scored.push({ + r, + s + }); + }); + if (!scored.length) return null; + let max = 0; + scored.forEach(x => { + if (x.s > max) max = x.s; + }); + let cand = scored.filter(x => x.s === max).map(x => x.r); + if (cand.length > 1) { + const vals = cand.map(c => typeof c.value === 'number' ? c.value : null).filter(v => v != null).sort((a, b) => a - b); + if (vals.length) { + const m = vals[Math.floor(vals.length / 2)]; + cand = cand.slice().sort((a, b) => Math.abs((a.value ?? m) - m) - Math.abs((b.value ?? m) - m)); + } + if (cand.length > 1) { + cand.sort((a, b) => (a.name?.length || 0) - (b.name?.length || 0)); + } + } + return cand[0] || null; +} +function isRefUnset(shiftSt, curveIdx, list) { + const name = shiftSt?.shifts?.[curveIdx]?.ref?.name || ''; + if (!name || name === PLACEHOLDER) return true; + return !(list || []).some(r => r.name === name); +} +const Layout = _ref => { + let { + classes, + feature, + hasEdit, + layoutSt, + setShiftRefAct, + updateLayoutAct, + curveSt, + shiftSt + } = _ref; + const { + curveIdx + } = curveSt; + const list = (0, _list_shift.getListShift)(layoutSt) || []; + const unset = isRefUnset(shiftSt, curveIdx, list); + const key = solventKeyOf(feature); + const best = pickBestRef(list, key); + (0, _react.useEffect)(() => { + if (unset && best) setShiftRefAct({ + dataToSet: best, + curveIdx + }); + }, [unset, best, curveIdx, setShiftRefAct]); + return /*#__PURE__*/(0, _jsxRuntime.jsxs)("span", { + className: classes.groupRight, + children: [layoutSelect(classes, layoutSt, updateLayoutAct), shiftSelect(classes, layoutSt, setShiftRefAct, shiftSt, curveSt), /*#__PURE__*/(0, _jsxRuntime.jsx)(_r02_scan.default, { + feature: feature, + hasEdit: hasEdit + })] + }); +}; +const mapStateToProps = (state, props) => ( +// eslint-disable-line +{ + layoutSt: state.layout, + curveSt: state.curve, + shiftSt: state.shift +}); +const mapDispatchToProps = dispatch => (0, _redux.bindActionCreators)({ + setShiftRefAct: _shift.setShiftRef, + updateLayoutAct: _layout.updateLayout +}, dispatch); +Layout.propTypes = { + classes: _propTypes.default.object.isRequired, + feature: _propTypes.default.object.isRequired, + hasEdit: _propTypes.default.bool.isRequired, + layoutSt: _propTypes.default.string.isRequired, + setShiftRefAct: _propTypes.default.func.isRequired, + updateLayoutAct: _propTypes.default.func.isRequired, + curveSt: _propTypes.default.object.isRequired, + shiftSt: _propTypes.default.object.isRequired +}; +var _default = exports.default = (0, _reactRedux.connect)(mapStateToProps, mapDispatchToProps)((0, _withStyles.default)(styles)(Layout)); \ No newline at end of file diff --git a/dist/components/cmd_bar/r02_scan.js b/dist/components/cmd_bar/r02_scan.js new file mode 100644 index 00000000..9a481766 --- /dev/null +++ b/dist/components/cmd_bar/r02_scan.js @@ -0,0 +1,133 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; +var _react = _interopRequireDefault(require("react")); +var _propTypes = _interopRequireDefault(require("prop-types")); +var _classnames = _interopRequireDefault(require("classnames")); +var _reactRedux = require("react-redux"); +var _redux = require("redux"); +var _material = require("@mui/material"); +var _styles = require("@mui/styles"); +var _CloudDoneOutlined = _interopRequireDefault(require("@mui/icons-material/CloudDoneOutlined")); +var _HowToRegOutlined = _interopRequireDefault(require("@mui/icons-material/HowToRegOutlined")); +var _RefreshOutlined = _interopRequireDefault(require("@mui/icons-material/RefreshOutlined")); +var _scan = require("../../actions/scan"); +var _common = require("./common"); +var _jsxRuntime = require("react/jsx-runtime"); +/* eslint-disable prefer-object-spread, function-paren-newline, +react/function-component-definition */ + +const styles = () => Object.assign({ + fieldScan: { + width: 90 + } +}, _common.commonStyle); +const restoreIcon = (classes, hasEdit, isEdit) => hasEdit && isEdit ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_HowToRegOutlined.default, { + className: classes.icon +}) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_CloudDoneOutlined.default, { + className: classes.icon +}); +const restoreTp = (hasEdit, isEdit) => hasEdit && isEdit ? 'User Defined Scan' : 'Auto Picked Scan'; +const btnRestore = (classes, hasEdit, isEdit, toggleEditAct) => /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Tooltip, { + title: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: "txt-sv-tp", + children: restoreTp(hasEdit, isEdit) + }), + children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_common.MuButton, { + className: (0, _classnames.default)('btn-sv-bar-scanrst'), + disabled: !hasEdit, + onClick: toggleEditAct, + children: restoreIcon(classes, hasEdit, isEdit) + }) +}); +const btnRrfresh = (classes, disabled, refreshAct) => /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Tooltip, { + title: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: "txt-sv-tp", + children: "Refresh Scan" + }), + children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_common.MuButton, { + className: (0, _classnames.default)('btn-sv-bar-scanrfs'), + disabled: disabled, + onClick: refreshAct, + children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_RefreshOutlined.default, { + className: classes.icon + }) + }) +}); +const scanSelect = (classes, feature, layoutSt, scanSt, onChange) => { + const { + target, + count + } = scanSt; + if (!count) return null; + const range = [...Array(count + 1).keys()].slice(1); + const content = range.map(num => /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.MenuItem, { + value: num, + children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: (0, _classnames.default)(classes.txtOpt, 'option-sv-bar-scan'), + children: `scan ${num}` + }) + }, num)); + const defaultValue = scanSt.isAuto || !feature.scanEditTarget ? feature.scanAutoTarget : feature.scanEditTarget; + const selValue = target || defaultValue || 1; + return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_material.FormControl, { + className: (0, _classnames.default)(classes.fieldScan), + variant: "outlined", + children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_material.InputLabel, { + id: "select-scan-label", + className: (0, _classnames.default)(classes.selectLabel, 'select-sv-bar-label'), + children: "Current Scan" + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Select, { + labelId: "select-scan-label", + label: "Current Scan", + value: selValue, + onChange: onChange, + className: (0, _classnames.default)(classes.selectInput, 'input-sv-bar-scan'), + children: content + })] + }); +}; +const Scan = _ref => { + let { + classes, + feature, + hasEdit, + layoutSt, + scanSt, + setScanTargetAct, + resetScanTargetAct, + toggleScanIsAutoAct + } = _ref; + const isMs = ['MS'].indexOf(layoutSt) >= 0; + if (!isMs) return null; + const onChange = e => setScanTargetAct(e.target.value); + return /*#__PURE__*/(0, _jsxRuntime.jsxs)("span", { + children: [scanSelect(classes, feature, layoutSt, scanSt, onChange), btnRrfresh(classes, false, resetScanTargetAct), btnRestore(classes, hasEdit, !scanSt.isAuto, toggleScanIsAutoAct)] + }); +}; +const mapStateToProps = (state, props) => ( +// eslint-disable-line +{ + layoutSt: state.layout, + scanSt: state.scan +}); +const mapDispatchToProps = dispatch => (0, _redux.bindActionCreators)({ + setScanTargetAct: _scan.setScanTarget, + resetScanTargetAct: _scan.resetScanTarget, + toggleScanIsAutoAct: _scan.toggleScanIsAuto +}, dispatch); +Scan.propTypes = { + classes: _propTypes.default.object.isRequired, + feature: _propTypes.default.object.isRequired, + hasEdit: _propTypes.default.bool.isRequired, + layoutSt: _propTypes.default.string.isRequired, + scanSt: _propTypes.default.object.isRequired, + setScanTargetAct: _propTypes.default.func.isRequired, + resetScanTargetAct: _propTypes.default.func.isRequired, + toggleScanIsAutoAct: _propTypes.default.func.isRequired +}; +var _default = exports.default = (0, _redux.compose)((0, _reactRedux.connect)(mapStateToProps, mapDispatchToProps), (0, _styles.withStyles)(styles))(Scan); \ No newline at end of file diff --git a/dist/components/cmd_bar/r03_threshold.js b/dist/components/cmd_bar/r03_threshold.js new file mode 100644 index 00000000..87ec722b --- /dev/null +++ b/dist/components/cmd_bar/r03_threshold.js @@ -0,0 +1,162 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; +var _react = _interopRequireDefault(require("react")); +var _propTypes = _interopRequireDefault(require("prop-types")); +var _classnames = _interopRequireDefault(require("classnames")); +var _reactRedux = require("react-redux"); +var _redux = require("redux"); +var _material = require("@mui/material"); +var _styles = require("@mui/styles"); +var _CloudDoneOutlined = _interopRequireDefault(require("@mui/icons-material/CloudDoneOutlined")); +var _HowToRegOutlined = _interopRequireDefault(require("@mui/icons-material/HowToRegOutlined")); +var _RefreshOutlined = _interopRequireDefault(require("@mui/icons-material/RefreshOutlined")); +var _cfg = _interopRequireDefault(require("../../helpers/cfg")); +var _threshold = require("../../actions/threshold"); +var _common = require("./common"); +var _jsxRuntime = require("react/jsx-runtime"); +/* eslint-disable prefer-object-spread, function-paren-newline, +react/function-component-definition */ + +const styles = () => Object.assign({ + field: { + width: 110 + }, + txtIcon: {} +}, _common.commonStyle); +const txtPercent = () => /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.InputAdornment, { + position: "end", + children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: "txt-percent", + children: "%" + }) +}); +const setThreshold = (classes, thresVal, updateThresholdValueAct, curveSt) => { + const { + curveIdx + } = curveSt; + const onBlur = e => updateThresholdValueAct({ + value: e.target.value, + curveIdx + }); + const onChange = e => updateThresholdValueAct({ + value: e.target.value, + curveIdx + }); + const onEnterPress = e => { + if (e.key === 'Enter') { + updateThresholdValueAct({ + value: e.target.value, + curveIdx + }); + } + }; + return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_material.FormControl, { + variant: "outlined", + children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_material.TextField, { + className: classes.field, + id: "outlined-name", + placeholder: "N.A.", + type: "number", + value: thresVal || 0.01, + margin: "none", + InputProps: { + endAdornment: txtPercent(), + className: (0, _classnames.default)(classes.txtInput, 'txtfield-sv-bar-input'), + inputProps: { + min: 0.01 + } + }, + onChange: onChange, + onBlur: onBlur, + onKeyPress: onEnterPress, + variant: "outlined" + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.InputLabel, { + className: (0, _classnames.default)(classes.txtLabelBottomInput), + children: "Threshold" + })] + }); +}; +const restoreIcon = (classes, hasEdit, isEdit) => hasEdit && isEdit ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_HowToRegOutlined.default, { + className: classes.icon +}) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_CloudDoneOutlined.default, { + className: classes.icon +}); +const restoreTp = (hasEdit, isEdit) => hasEdit && isEdit ? 'User Defined Threshold' : 'Auto Picked Threshold'; +const Threshold = _ref => { + let { + classes, + feature, + hasEdit, + hideThresSt, + thresValSt, + isEditSt, + curveSt, + updateThresholdValueAct, + resetThresholdValueAct, + toggleThresholdIsEditAct + } = _ref; + const thresVal = thresValSt || feature.thresRef; + return /*#__PURE__*/(0, _jsxRuntime.jsxs)("span", { + className: classes.groupRight, + children: [setThreshold(classes, thresVal, updateThresholdValueAct, curveSt), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Tooltip, { + title: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: "txt-sv-tp", + children: "Restore Threshold" + }), + children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_common.MuButton, { + className: (0, _classnames.default)('btn-sv-bar-thresref'), + disabled: _cfg.default.btnCmdThres(thresVal), + onClick: resetThresholdValueAct, + children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_RefreshOutlined.default, { + className: classes.icon + }) + }) + }) + }), hideThresSt ? null : /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Tooltip, { + title: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: "txt-sv-tp", + children: restoreTp(hasEdit, isEditSt) + }), + children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_common.MuButton, { + className: (0, _classnames.default)('btn-sv-bar-thresrst'), + disabled: _cfg.default.btnCmdThres(thresVal), + onClick: toggleThresholdIsEditAct, + children: restoreIcon(classes, hasEdit, isEditSt) + }) + }) + })] + }); +}; +const mapStateToProps = (state, props) => ( +// eslint-disable-line +{ + hideThresSt: _cfg.default.hideCmdThres(state.layout), + isEditSt: state.threshold.list[state.curve.curveIdx].isEdit, + thresValSt: parseFloat(state.threshold.list[state.curve.curveIdx].value) || 0, + curveSt: state.curve +}); +const mapDispatchToProps = dispatch => (0, _redux.bindActionCreators)({ + updateThresholdValueAct: _threshold.updateThresholdValue, + resetThresholdValueAct: _threshold.resetThresholdValue, + toggleThresholdIsEditAct: _threshold.toggleThresholdIsEdit +}, dispatch); +Threshold.propTypes = { + classes: _propTypes.default.object.isRequired, + feature: _propTypes.default.object.isRequired, + hasEdit: _propTypes.default.bool.isRequired, + hideThresSt: _propTypes.default.bool.isRequired, + isEditSt: _propTypes.default.bool.isRequired, + thresValSt: _propTypes.default.number.isRequired, + curveSt: _propTypes.default.object.isRequired, + updateThresholdValueAct: _propTypes.default.func.isRequired, + resetThresholdValueAct: _propTypes.default.func.isRequired, + toggleThresholdIsEditAct: _propTypes.default.func.isRequired +}; +var _default = exports.default = (0, _reactRedux.connect)(mapStateToProps, mapDispatchToProps)((0, _styles.withStyles)(styles)(Threshold)); \ No newline at end of file diff --git a/dist/components/cmd_bar/r04_submit.js b/dist/components/cmd_bar/r04_submit.js new file mode 100644 index 00000000..4e115a0a --- /dev/null +++ b/dist/components/cmd_bar/r04_submit.js @@ -0,0 +1,262 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; +var _react = _interopRequireDefault(require("react")); +var _propTypes = _interopRequireDefault(require("prop-types")); +var _classnames = _interopRequireDefault(require("classnames")); +var _reactRedux = require("react-redux"); +var _redux = require("redux"); +var _material = require("@mui/material"); +var _styles = require("@mui/styles"); +var _submit = require("../../actions/submit"); +var _r05_submit_btn = _interopRequireDefault(require("./r05_submit_btn")); +var _r06_predict_btn = _interopRequireDefault(require("./r06_predict_btn")); +var _common = require("./common"); +var _format = _interopRequireDefault(require("../../helpers/format")); +var _jsxRuntime = require("react/jsx-runtime"); +/* eslint-disable prefer-object-spread, function-paren-newline, +react/function-component-definition */ + +const styles = () => Object.assign({ + fieldOrder: { + width: 90 + }, + fieldIntensity: { + width: 90 + }, + fieldDecimal: { + width: 80 + }, + fieldOpertaion: { + width: 120 + } +}, _common.commonStyle); +const ascendSelect = (classes, hideSwitch, isAscendSt, toggleIsAscendAct) => { + if (hideSwitch) return null; + return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_material.FormControl, { + className: (0, _classnames.default)(classes.fieldOrder), + variant: "outlined", + children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_material.InputLabel, { + id: "select-sort-peaks-label", + className: (0, _classnames.default)(classes.selectLabel, 'select-sv-bar-label'), + children: "Write Peaks" + }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_material.Select, { + labelId: "select-sort-peaks-label", + label: "Write Peaks", + value: isAscendSt, + onChange: toggleIsAscendAct, + className: (0, _classnames.default)(classes.selectInput, 'input-sv-bar-order'), + children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_material.MenuItem, { + value: true, + children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: (0, _classnames.default)(classes.txtOpt, 'option-sv-bar-ascend'), + children: "Ascend" + }) + }, "ascend"), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.MenuItem, { + value: false, + children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: (0, _classnames.default)(classes.txtOpt, 'option-sv-bar-descend'), + children: "Descend" + }) + }, "descend")] + })] + }); +}; +const intensitySelect = (classes, hideSwitch, isIntensitySt, toggleIsIntensityAct) => { + if (hideSwitch) return null; + return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_material.FormControl, { + className: (0, _classnames.default)(classes.fieldIntensity), + variant: "outlined", + children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_material.InputLabel, { + id: "select-intensity-label", + className: (0, _classnames.default)(classes.selectLabel, 'select-sv-bar-label'), + children: "Write Intensity" + }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_material.Select, { + labelId: "select-intensity-label", + label: "Write Intensity", + value: isIntensitySt, + onChange: toggleIsIntensityAct, + className: (0, _classnames.default)(classes.selectInput, 'input-sv-bar-intensity') + // input={ + // ( + // + // ) + // } + , + children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_material.MenuItem, { + value: true, + children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: (0, _classnames.default)(classes.txtOpt, 'option-sv-bar-show'), + children: "Show" + }) + }, "ascend"), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.MenuItem, { + value: false, + children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: (0, _classnames.default)(classes.txtOpt, 'option-sv-bar-hide'), + children: "Hide" + }) + }, "descend")] + })] + }); +}; +const decimalSelect = (classes, hideSwitch, decimalSt, updateDecimalAct) => { + if (hideSwitch) return null; + const decimals = [0, 1, 2, 3, 4]; + const options = decimals.map(d => /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.MenuItem, { + value: d, + children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: (0, _classnames.default)(classes.txtOpt, 'option-sv-bar-decimal'), + children: d + }) + }, d)); + return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_material.FormControl, { + className: (0, _classnames.default)(classes.fieldDecimal), + variant: "outlined", + children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_material.InputLabel, { + id: "select-decimal-label", + className: (0, _classnames.default)(classes.selectLabel, 'select-sv-bar-label'), + children: "Decimal" + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Select, { + labelId: "select-decimal-label", + label: "Decimal", + value: decimalSt, + onChange: updateDecimalAct, + className: (0, _classnames.default)(classes.selectInput, 'input-sv-bar-decimal') + // input={ + // ( + // + // ) + // } + , + children: options + })] + }); +}; +const operationSelect = (classes, operations, operation, onChangeSelect) => { + const options = operations.map(o => /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.MenuItem, { + value: o.name, + children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: (0, _classnames.default)(classes.txtOpt, 'option-sv-bar-operation'), + children: o.name + }) + }, o.name)); + const selectedValue = operation.name || operations[0].name; + return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_material.FormControl, { + className: (0, _classnames.default)(classes.fieldOpertaion), + variant: "outlined", + children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_material.InputLabel, { + id: "select-submit-label", + className: (0, _classnames.default)(classes.selectLabel, 'select-sv-bar-label'), + children: "Submit" + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Select, { + labelId: "select-submit-label", + label: "Submit", + value: selectedValue, + onChange: onChangeSelect, + className: (0, _classnames.default)(classes.selectInput, 'input-sv-bar-operation') + // input={ + // ( + // + // ) + // } + , + children: options + })] + }); +}; +const selectOperation = (name, operations, updateOperationAct) => { + let operation = false; + operations.forEach(o => { + if (o.name === name) { + operation = o; + } + }); + updateOperationAct(operation); +}; +const Submit = _ref => { + let { + operations, + classes, + feature, + forecast, + editorOnly, + hideSwitch, + disabled, + isAscendSt, + isIntensitySt, + operationSt, + decimalSt, + isEmWaveSt, + layoutSt, + toggleIsAscendAct, + toggleIsIntensityAct, + updateOperationAct, + updateDecimalAct + } = _ref; + const onChangeSelect = e => selectOperation(e.target.value, operations, updateOperationAct); + if (!operations || operations.length === 0) return null; + const allowPredictInEditorOnly = _format.default.is1HLayout(layoutSt) || _format.default.is13CLayout(layoutSt) || _format.default.isIrLayout(layoutSt); + const shouldShowPredict = !editorOnly || allowPredictInEditorOnly; + return /*#__PURE__*/(0, _jsxRuntime.jsxs)("span", { + className: classes.groupRightMost, + children: [ascendSelect(classes, hideSwitch, isAscendSt, toggleIsAscendAct), intensitySelect(classes, hideSwitch || !isEmWaveSt, isIntensitySt, toggleIsIntensityAct), decimalSelect(classes, hideSwitch, decimalSt, updateDecimalAct), shouldShowPredict ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_r06_predict_btn.default, { + feature: feature, + forecast: forecast + }) : null, operationSelect(classes, operations, operationSt, onChangeSelect), /*#__PURE__*/(0, _jsxRuntime.jsx)(_r05_submit_btn.default, { + feature: feature, + isAscend: isAscendSt, + isIntensity: isIntensitySt, + operation: operationSt, + disabled: disabled + })] + }); +}; +const mapStateToProps = (state, props) => ( +// eslint-disable-line +{ + layoutSt: state.layout, + isEmWaveSt: _format.default.isEmWaveLayout(state.layout), + isAscendSt: state.submit.isAscend, + isIntensitySt: state.submit.isIntensity, + decimalSt: state.submit.decimal, + operationSt: state.submit.operation +}); +const mapDispatchToProps = dispatch => (0, _redux.bindActionCreators)({ + toggleIsAscendAct: _submit.toggleIsAscend, + toggleIsIntensityAct: _submit.toggleIsIntensity, + updateOperationAct: _submit.updateOperation, + updateDecimalAct: _submit.updateDecimal +}, dispatch); +Submit.propTypes = { + classes: _propTypes.default.object.isRequired, + feature: _propTypes.default.object.isRequired, + forecast: _propTypes.default.object.isRequired, + editorOnly: _propTypes.default.bool.isRequired, + operations: _propTypes.default.array.isRequired, + operationSt: _propTypes.default.object.isRequired, + hideSwitch: _propTypes.default.bool.isRequired, + disabled: _propTypes.default.bool.isRequired, + layoutSt: _propTypes.default.string.isRequired, + isAscendSt: _propTypes.default.bool.isRequired, + isIntensitySt: _propTypes.default.bool.isRequired, + isEmWaveSt: _propTypes.default.bool.isRequired, + decimalSt: _propTypes.default.number.isRequired, + toggleIsAscendAct: _propTypes.default.func.isRequired, + toggleIsIntensityAct: _propTypes.default.func.isRequired, + updateOperationAct: _propTypes.default.func.isRequired, + updateDecimalAct: _propTypes.default.func.isRequired +}; +var _default = exports.default = (0, _redux.compose)((0, _reactRedux.connect)(mapStateToProps, mapDispatchToProps), (0, _styles.withStyles)(styles))(Submit); \ No newline at end of file diff --git a/dist/components/cmd_bar/r05_submit_btn.js b/dist/components/cmd_bar/r05_submit_btn.js new file mode 100644 index 00000000..1dd6c42a --- /dev/null +++ b/dist/components/cmd_bar/r05_submit_btn.js @@ -0,0 +1,155 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; +var _react = _interopRequireDefault(require("react")); +var _propTypes = _interopRequireDefault(require("prop-types")); +var _reactRedux = require("react-redux"); +var _classnames = _interopRequireDefault(require("classnames")); +var _redux = require("redux"); +var _Tooltip = _interopRequireDefault(require("@mui/material/Tooltip")); +var _PlayCircleOutline = _interopRequireDefault(require("@mui/icons-material/PlayCircleOutline")); +var _styles = require("@mui/styles"); +var _chem = require("../../helpers/chem"); +var _common = require("./common"); +var _extractPeaksEdit = require("../../helpers/extractPeaksEdit"); +var _jsxRuntime = require("react/jsx-runtime"); +/* eslint-disable prefer-object-spread, function-paren-newline, +react/function-component-definition, function-call-argument-newline, +react/require-default-props */ + +const styles = () => Object.assign({}, _common.commonStyle); +const onClickCb = (operation, peaksEdit, isAscend, isIntensity, scan, thres, layoutSt, shiftSt, analysis, decimalSt, integrationSt, multiplicitySt, allIntegrationSt, aucValues, waveLengthSt, cyclicvoltaSt, curveSt, axesUnitsSt, detectorSt, dscMetaData) => () => { + operation({ + peaks: peaksEdit, + layout: layoutSt, + shift: shiftSt, + scan, + thres, + isAscend, + isIntensity, + analysis, + decimal: decimalSt, + integration: integrationSt, + multiplicity: multiplicitySt, + allIntegration: allIntegrationSt, + aucValues, + waveLength: waveLengthSt, + cyclicvoltaSt, + curveSt, + axesUnitsSt, + detectorSt, + dscMetaData + }); +}; +const BtnSubmit = _ref => { + let { + classes, + operation, + feature, + isAscend, + isIntensity, + editPeakSt, + thresSt, + layoutSt, + shiftSt, + scanSt, + forecastSt, + decimalSt, + integrationSt, + multiplicitySt, + allIntegrationSt, + waveLengthSt, + cyclicvoltaSt, + curveSt, + axesUnitsSt, + detectorSt, + metaSt + } = _ref; + const peaksEdit = (0, _extractPeaksEdit.extractPeaksEdit)(feature, editPeakSt, thresSt, shiftSt, layoutSt); + // const disBtn = peaksEdit.length === 0 || statusSt.btnSubmit || disabled; + const scan = (0, _chem.Convert2Scan)(feature, scanSt); + const thres = (0, _chem.Convert2Thres)(feature, thresSt); + const aucValues = (0, _extractPeaksEdit.extractAreaUnderCurve)(allIntegrationSt, integrationSt, layoutSt); + const { + dscMetaData + } = metaSt; + const predictionsByCurve = forecastSt.predictionsByCurve || {}; + const hasCurvePredictions = Object.prototype.hasOwnProperty.call(predictionsByCurve, curveSt.curveIdx); + const hasAnyCurvePredictions = Object.keys(predictionsByCurve).length > 0; + const emptyPredictions = { + outline: {}, + output: { + result: [] + } + }; + let activePredictions = forecastSt.predictions; + if (hasCurvePredictions) { + activePredictions = predictionsByCurve[curveSt.curveIdx]; + } else if (hasAnyCurvePredictions) { + activePredictions = emptyPredictions; + } + if (!operation) return null; + return /*#__PURE__*/(0, _jsxRuntime.jsx)(_Tooltip.default, { + title: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: "txt-sv-tp", + children: "Submit" + }), + children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_common.MuButton, { + className: (0, _classnames.default)('btn-sv-bar-submit'), + color: "primary", + onClick: onClickCb(operation.value, peaksEdit, isAscend, isIntensity, scan, thres, layoutSt, shiftSt, activePredictions, decimalSt, integrationSt, multiplicitySt, allIntegrationSt, aucValues, waveLengthSt, cyclicvoltaSt, curveSt, axesUnitsSt, detectorSt, dscMetaData), + children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_PlayCircleOutline.default, { + className: classes.icon + }) + }) + }); +}; +const mapStateToProps = (state, props) => ( +// eslint-disable-line +{ + editPeakSt: state.editPeak.present, + thresSt: state.threshold.list[state.curve.curveIdx], + layoutSt: state.layout, + shiftSt: state.shift, + scanSt: state.scan, + forecastSt: state.forecast, + decimalSt: state.submit.decimal, + integrationSt: state.integration.present, + multiplicitySt: state.multiplicity.present, + allIntegrationSt: state.integration.past.concat(state.integration.present), + waveLengthSt: state.wavelength, + cyclicvoltaSt: state.cyclicvolta, + curveSt: state.curve, + axesUnitsSt: state.axesUnits, + detectorSt: state.detector, + metaSt: state.meta +}); +const mapDispatchToProps = dispatch => (0, _redux.bindActionCreators)({}, dispatch); +BtnSubmit.propTypes = { + classes: _propTypes.default.object.isRequired, + feature: _propTypes.default.object.isRequired, + isAscend: _propTypes.default.bool.isRequired, + isIntensity: _propTypes.default.bool.isRequired, + operation: _propTypes.default.oneOfType([_propTypes.default.object, _propTypes.default.bool]).isRequired, + editPeakSt: _propTypes.default.object.isRequired, + thresSt: _propTypes.default.object.isRequired, + layoutSt: _propTypes.default.string.isRequired, + shiftSt: _propTypes.default.object.isRequired, + scanSt: _propTypes.default.object.isRequired, + forecastSt: _propTypes.default.object.isRequired, + decimalSt: _propTypes.default.number.isRequired, + integrationSt: _propTypes.default.object.isRequired, + multiplicitySt: _propTypes.default.object.isRequired, + allIntegrationSt: _propTypes.default.object.isRequired, + waveLengthSt: _propTypes.default.object.isRequired, + cyclicvoltaSt: _propTypes.default.object.isRequired, + curveSt: _propTypes.default.object, + axesUnitsSt: _propTypes.default.object.isRequired, + detectorSt: _propTypes.default.object.isRequired, + metaSt: _propTypes.default.object.isRequired +}; +var _default = exports.default = (0, _redux.compose)((0, _reactRedux.connect)(mapStateToProps, mapDispatchToProps), (0, _styles.withStyles)(styles))(BtnSubmit); \ No newline at end of file diff --git a/dist/components/cmd_bar/r06_predict_btn.js b/dist/components/cmd_bar/r06_predict_btn.js new file mode 100644 index 00000000..c1100381 --- /dev/null +++ b/dist/components/cmd_bar/r06_predict_btn.js @@ -0,0 +1,253 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; +var _react = _interopRequireDefault(require("react")); +var _propTypes = _interopRequireDefault(require("prop-types")); +var _reactRedux = require("react-redux"); +var _classnames = _interopRequireDefault(require("classnames")); +var _redux = require("redux"); +var _material = require("@mui/material"); +var _GpsFixedOutlined = _interopRequireDefault(require("@mui/icons-material/GpsFixedOutlined")); +var _HelpOutlineOutlined = _interopRequireDefault(require("@mui/icons-material/HelpOutlineOutlined")); +var _styles = require("@mui/styles"); +var _common = require("./common"); +var _format = _interopRequireDefault(require("../../helpers/format")); +var _carbonFeatures = require("../../helpers/carbonFeatures"); +var _extractPeaksEdit = require("../../helpers/extractPeaksEdit"); +var _ui = require("../../actions/ui"); +var _list_ui = require("../../constants/list_ui"); +var _chem = require("../../helpers/chem"); +var _jsxRuntime = require("react/jsx-runtime"); +/* eslint-disable prefer-object-spread, function-paren-newline, +max-len, react/function-component-definition, +function-call-argument-newline, react/require-default-props */ + +const styles = () => Object.assign({}, _common.commonStyle, { + tTxt: { + fontSize: '0.8rem', + fontFamily: 'Helvetica', + marginRight: 5 + }, + btnWidthUnknown: { + minWidth: 30, + width: 30 + }, + btnWidthIr: { + minWidth: 30, + width: 30 + }, + btnWidthNmr: { + minWidth: 80, + width: 80 + } +}); +const MuPredictButton = (0, _styles.withStyles)({ + root: { + border: '1px solid #ccc', + borderRadius: 4, + fontFamily: 'Helvetica', + fontSize: 20, + height: 30, + lineHeight: '20px', + padding: 0 + } +})(_material.Button); +const onClickFail = (layoutSt, simuCount, realCount) => { + const feature = _format.default.is13CLayout(layoutSt) ? 'peak' : 'multiplet'; + return () => alert(`Selected ${feature} count (${realCount}) must be larger than 0, and must be eqal or less than simulated count (${simuCount}).`); // eslint-disable-line +}; +const onClickReady = (forecast, peaksEdit, layoutSt, scan, shiftSt, thres, analysis, integrationSt, multiplicitySt, setUiViewerTypeAct, curveSt) => { + const { + btnCb + } = forecast; + if (!btnCb) { + return () => alert('[Developer Warning] You need to implement btnCb in forecast!'); // eslint-disable-line + } + return () => { + setUiViewerTypeAct(_list_ui.LIST_UI_VIEWER_TYPE.ANALYSIS); + return btnCb({ + peaks: peaksEdit, + layout: layoutSt, + scan, + thres, + analysis, + integration: integrationSt, + multiplicity: multiplicitySt, + shift: shiftSt, + curveSt + }); + }; +}; +const onClicUnknown = (feature, forecast, peaksEdit, layoutSt, scan, shiftSt, thres, analysis, integrationSt, multiplicitySt, curveSt) => { + const { + refreshCb + } = forecast; + if (!refreshCb) { + return () => alert('[Developer Warning] You need to implement refreshCb in forecast!'); // eslint-disable-line + } + return () => refreshCb({ + peaks: peaksEdit, + layout: layoutSt, + scan, + shift: shiftSt, + thres, + analysis, + integration: integrationSt, + multiplicity: multiplicitySt, + curveSt + }); +}; +const counterText = (classes, isIr, realCount, uniqCount, simuCount) => isIr ? null : /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: (0, _classnames.default)(classes.tTxt, 'txt-sv-panel-txt'), + children: `${realCount}/${uniqCount}/${simuCount}` +}); +const renderBtnPredict = (classes, isIr, realCount, uniqCount, simuCount, color, btnWidthCls, onClick) => /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Tooltip, { + title: /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", { + children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: "txt-sv-tp", + children: "Predict" + }), /*#__PURE__*/(0, _jsxRuntime.jsx)("br", {}), /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: "txt-sv-tp", + children: "- Selected features must be eqal or less than simulated features." + })] + }), + children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(MuPredictButton, { + className: (0, _classnames.default)('btn-sv-bar-submit', btnWidthCls), + style: { + color + }, + onClick: onClick, + children: [counterText(classes, isIr, realCount, uniqCount, simuCount), /*#__PURE__*/(0, _jsxRuntime.jsx)(_GpsFixedOutlined.default, { + className: classes.icon + })] + }) +}); +const renderBtnUnknown = (classes, onClick) => /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Tooltip, { + title: /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", { + children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: "txt-sv-tp", + children: "Refresh Simulation" + }), /*#__PURE__*/(0, _jsxRuntime.jsx)("br", {}), /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: "txt-sv-tp", + children: "- Simulation must be refreshed before making a prediction." + }), /*#__PURE__*/(0, _jsxRuntime.jsx)("br", {}), /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: "txt-sv-tp", + children: "- If you continue to see this button after clicking it, the server is not ready. Please wait for a while." + })] + }), + children: /*#__PURE__*/(0, _jsxRuntime.jsx)(MuPredictButton, { + className: (0, _classnames.default)('btn-sv-bar-submit', classes.btnWidthUnknown), + style: { + color: 'orange' + }, + onClick: onClick, + children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_HelpOutlineOutlined.default, { + className: classes.icon + }) + }) +}); +const BtnPredict = _ref => { + let { + classes, + feature, + forecast, + layoutSt, + simulationSt, + editPeakSt, + scanSt, + shiftSt, + thresSt, + integrationSt, + multiplicitySt, + forecastSt, + setUiViewerTypeAct, + curveSt + } = _ref; + const is13Cor1H = _format.default.is13CLayout(layoutSt) || _format.default.is1HLayout(layoutSt); + const isIr = _format.default.isIrLayout(layoutSt); + if (!(is13Cor1H || isIr)) return null; + const oriPeaksEdit = (0, _extractPeaksEdit.extractPeaksEdit)(feature, editPeakSt, thresSt, shiftSt, layoutSt); + const peaksEdit = _format.default.rmShiftFromPeaks(oriPeaksEdit, shiftSt); + const scan = (0, _chem.Convert2Scan)(feature, scanSt); + const thres = (0, _chem.Convert2Thres)(feature, thresSt); + const simuCount = simulationSt.nmrSimPeaks.length; + const uniqCount = [...new Set(simulationSt.nmrSimPeaks)].length; + const { + curveIdx + } = curveSt; + const predictionsByCurve = forecastSt && forecastSt.predictionsByCurve || {}; + const hasCurvePredictions = Object.prototype.hasOwnProperty.call(predictionsByCurve, curveIdx); + const hasAnyCurvePredictions = Object.keys(predictionsByCurve).length > 0; + const emptyPredictions = { + outline: {}, + output: { + result: [] + } + }; + let analysisPredictions = forecastSt && forecastSt.predictions || forecast.predictions; + if (hasCurvePredictions) { + analysisPredictions = predictionsByCurve[curveIdx]; + } else if (hasAnyCurvePredictions) { + analysisPredictions = emptyPredictions; + } + let realCount = 0; + if (_format.default.is13CLayout(layoutSt)) { + realCount = (0, _carbonFeatures.carbonFeatures)(peaksEdit, multiplicitySt).length; + } else { + const { + multiplicities + } = multiplicitySt; + const selectedMultiplicity = multiplicities[curveIdx]; + const { + stack + } = selectedMultiplicity; + realCount = stack.length; + } + if (is13Cor1H && simuCount === 0) { + const onClickUnknownCb = onClicUnknown(feature, forecast, peaksEdit, layoutSt, scan, shiftSt, thres, analysisPredictions, integrationSt, multiplicitySt, curveSt); + return renderBtnUnknown(classes, onClickUnknownCb); + } + const predictable = isIr || simuCount >= realCount && realCount > 0; + const color = predictable ? 'green' : 'red'; + const onClick = predictable ? onClickReady(forecast, peaksEdit, layoutSt, scan, shiftSt, thres, analysisPredictions, integrationSt, multiplicitySt, setUiViewerTypeAct, curveSt) : onClickFail(layoutSt, simuCount, realCount); + const btnWidthCls = isIr ? classes.btnWidthIr : classes.btnWidthNmr; + return renderBtnPredict(classes, isIr, realCount, uniqCount, simuCount, color, btnWidthCls, onClick); +}; +const mapStateToProps = (state, props) => ( +// eslint-disable-line +{ + layoutSt: state.layout, + simulationSt: state.simulation, + editPeakSt: state.editPeak.present, + scanSt: state.scan, + shiftSt: state.shift, + thresSt: state.threshold.list[state.curve.curveIdx], + integrationSt: state.integration.present, + multiplicitySt: state.multiplicity.present, + curveSt: state.curve, + forecastSt: state.forecast +}); +const mapDispatchToProps = dispatch => (0, _redux.bindActionCreators)({ + setUiViewerTypeAct: _ui.setUiViewerType +}, dispatch); +BtnPredict.propTypes = { + classes: _propTypes.default.object.isRequired, + feature: _propTypes.default.object.isRequired, + forecast: _propTypes.default.object.isRequired, + layoutSt: _propTypes.default.string.isRequired, + simulationSt: _propTypes.default.array.isRequired, + editPeakSt: _propTypes.default.object.isRequired, + scanSt: _propTypes.default.object.isRequired, + shiftSt: _propTypes.default.object.isRequired, + thresSt: _propTypes.default.object.isRequired, + integrationSt: _propTypes.default.object.isRequired, + multiplicitySt: _propTypes.default.object.isRequired, + forecastSt: _propTypes.default.object.isRequired, + setUiViewerTypeAct: _propTypes.default.func.isRequired, + curveSt: _propTypes.default.object +}; +var _default = exports.default = (0, _redux.compose)((0, _reactRedux.connect)(mapStateToProps, mapDispatchToProps), (0, _styles.withStyles)(styles))(BtnPredict); \ No newline at end of file diff --git a/dist/components/cmd_bar/r07_wavelength_btn.js b/dist/components/cmd_bar/r07_wavelength_btn.js new file mode 100644 index 00000000..c24c1313 --- /dev/null +++ b/dist/components/cmd_bar/r07_wavelength_btn.js @@ -0,0 +1,89 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; +var _react = _interopRequireDefault(require("react")); +var _propTypes = _interopRequireDefault(require("prop-types")); +var _reactRedux = require("react-redux"); +var _classnames = _interopRequireDefault(require("classnames")); +var _redux = require("redux"); +var _material = require("@mui/material"); +var _withStyles = _interopRequireDefault(require("@mui/styles/withStyles")); +var _wavelength = require("../../actions/wavelength"); +var _format = _interopRequireDefault(require("../../helpers/format")); +var _common = require("./common"); +var _list_wavelength = require("../../constants/list_wavelength"); +var _jsxRuntime = require("react/jsx-runtime"); +/* eslint-disable prefer-object-spread, react/jsx-one-expression-per-line, +react/function-component-definition */ + +const styles = () => Object.assign({ + fieldShift: { + width: 160 + }, + fieldLayout: { + width: 100 + } +}, _common.commonStyle); +const wavelengthSelect = (classes, waveLengthSt, layoutSt, updateWaveLengthAct) => { + if (!_format.default.isXRDLayout(layoutSt)) { + return /*#__PURE__*/(0, _jsxRuntime.jsx)("i", {}); + } + const onChange = e => updateWaveLengthAct(e.target.value); + return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_material.FormControl, { + className: (0, _classnames.default)(classes.fieldLayout), + variant: "outlined", + children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_material.InputLabel, { + id: "select-wavelength-label", + className: (0, _classnames.default)(classes.selectLabel, 'select-sv-bar-label'), + children: "Wavelength" + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Select, { + labelId: "select-wavelength-label", + label: "Wavelength", + value: waveLengthSt, + onChange: onChange, + className: (0, _classnames.default)(classes.selectInput, 'input-sv-bar-layout'), + children: _list_wavelength.LIST_WAVE_LENGTH.map(item => { + // eslint-disable-line + return /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.MenuItem, { + value: item, + children: /*#__PURE__*/(0, _jsxRuntime.jsxs)("span", { + className: (0, _classnames.default)(classes.txtOpt, 'option-sv-bar-layout'), + children: [item.label, " (", item.value, " ", item.unit, ")"] + }) + }); + }) + })] + }); +}; +const Wavelength = _ref => { + let { + classes, + waveLengthSt, + layoutSt, + updateWaveLengthAct + } = _ref; + return /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: classes.groupRight, + children: wavelengthSelect(classes, waveLengthSt, layoutSt, updateWaveLengthAct) + }); +}; +const mapStateToProps = (state, props) => ( +// eslint-disable-line +{ + waveLengthSt: state.wavelength, + layoutSt: state.layout +}); +const mapDispatchToProps = dispatch => (0, _redux.bindActionCreators)({ + updateWaveLengthAct: _wavelength.updateWaveLength +}, dispatch); +Wavelength.propTypes = { + classes: _propTypes.default.object.isRequired, + layoutSt: _propTypes.default.string.isRequired, + waveLengthSt: _propTypes.default.object.isRequired, + updateWaveLengthAct: _propTypes.default.func.isRequired +}; +var _default = exports.default = (0, _reactRedux.connect)(mapStateToProps, mapDispatchToProps)((0, _withStyles.default)(styles)(Wavelength)); \ No newline at end of file diff --git a/dist/components/cmd_bar/r08_change_axes.js b/dist/components/cmd_bar/r08_change_axes.js new file mode 100644 index 00000000..c475cb85 --- /dev/null +++ b/dist/components/cmd_bar/r08_change_axes.js @@ -0,0 +1,173 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; +var _react = _interopRequireDefault(require("react")); +var _propTypes = _interopRequireDefault(require("prop-types")); +var _reactRedux = require("react-redux"); +var _classnames = _interopRequireDefault(require("classnames")); +var _redux = require("redux"); +var _material = require("@mui/material"); +var _withStyles = _interopRequireDefault(require("@mui/styles/withStyles")); +var _common = require("./common"); +var _list_layout = require("../../constants/list_layout"); +var _list_axes = require("../../constants/list_axes"); +var _axes = require("../../actions/axes"); +var _jsxRuntime = require("react/jsx-runtime"); +/* eslint-disable prefer-object-spread, react/jsx-one-expression-per-line, +react/function-component-definition, +max-len, no-unused-vars, no-multiple-empty-lines */ + +const listLayoutToShow = [_list_layout.LIST_LAYOUT.CYCLIC_VOLTAMMETRY]; +const styles = () => Object.assign({ + fieldShift: { + width: 160 + }, + fieldLayout: { + width: 100 + } +}, _common.commonStyle); +const axisX = (classes, layoutSt, axesUnitsSt, updateXAxisAct, curveSt) => { + const optionsAxisX = _list_axes.LIST_AXES.x; + const options = optionsAxisX[layoutSt]; + const { + curveIdx + } = curveSt; + const onChange = e => updateXAxisAct({ + value: e.target.value, + curveIndex: curveIdx + }); + const { + axes + } = axesUnitsSt; + let selectedAxes = axes[curveIdx]; + if (!selectedAxes) { + selectedAxes = { + xUnit: '', + yUnit: '' + }; + } + const { + xUnit + } = selectedAxes; + return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_material.FormControl, { + className: (0, _classnames.default)(classes.fieldLayout), + variant: "outlined", + children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Select, { + labelId: "select-x-axis-label", + label: "x-Axis", + value: xUnit, + onChange: onChange, + className: (0, _classnames.default)(classes.selectInput, 'input-sv-bar-layout'), + children: options.map(item => { + // eslint-disable-line + return /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.MenuItem, { + value: item, + children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: (0, _classnames.default)(classes.txtOpt, 'option-sv-bar-layout'), + children: item === '' ? 'Default' : item + }) + }, item); + }) + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.InputLabel, { + id: "select-x-axis-label", + className: (0, _classnames.default)(classes.txtLabelTopInput), + children: "x-Axis" + })] + }); +}; +const axisY = (classes, layoutSt, axesUnitsSt, updateYAxisAct, curveSt) => { + const optionsAxisX = _list_axes.LIST_AXES.y; + const options = optionsAxisX[layoutSt]; + const { + curveIdx + } = curveSt; + const onChange = e => updateYAxisAct({ + value: e.target.value, + curveIndex: curveIdx + }); + const { + axes + } = axesUnitsSt; + let selectedAxes = axes[curveIdx]; + if (!selectedAxes) { + selectedAxes = { + xUnit: '', + yUnit: '' + }; + } + const { + yUnit + } = selectedAxes; + return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_material.FormControl, { + className: (0, _classnames.default)(classes.fieldLayout), + variant: "outlined", + children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Select, { + labelId: "select-y-axis-label", + label: "y-Axis", + value: yUnit, + onChange: onChange, + className: (0, _classnames.default)(classes.selectInput, 'input-sv-bar-layout'), + children: options.map(item => { + // eslint-disable-line + return /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.MenuItem, { + value: item, + children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: (0, _classnames.default)(classes.txtOpt, 'option-sv-bar-layout'), + children: item === '' ? 'Default' : item + }) + }, item); + }) + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.InputLabel, { + id: "select-y-axis-label", + className: (0, _classnames.default)(classes.txtLabelTopInput), + children: "y-Axis" + })] + }); +}; +const showSelect = (classes, layoutSt, curveSt, axesUnitsSt, updateXAxisAct, updateYAxisAct) => { + if (!listLayoutToShow.includes(layoutSt)) { + return /*#__PURE__*/(0, _jsxRuntime.jsx)("i", {}); + } + return /*#__PURE__*/(0, _jsxRuntime.jsxs)("span", { + children: [axisX(classes, layoutSt, axesUnitsSt, updateXAxisAct, curveSt), axisY(classes, layoutSt, axesUnitsSt, updateYAxisAct, curveSt)] + }); +}; +const ChangeAxes = _ref => { + let { + classes, + layoutSt, + curveSt, + axesUnitsSt, + updateXAxisAct, + updateYAxisAct + } = _ref; + return /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: classes.groupRight, + "data-testid": "ChangeAxes", + children: showSelect(classes, layoutSt, curveSt, axesUnitsSt, updateXAxisAct, updateYAxisAct) + }); +}; +const mapStateToProps = (state, props) => ( +// eslint-disable-line +{ + layoutSt: state.layout, + curveSt: state.curve, + axesUnitsSt: state.axesUnits +}); +const mapDispatchToProps = dispatch => (0, _redux.bindActionCreators)({ + updateXAxisAct: _axes.updateXAxis, + updateYAxisAct: _axes.updateYAxis +}, dispatch); +ChangeAxes.propTypes = { + classes: _propTypes.default.object.isRequired, + layoutSt: _propTypes.default.string.isRequired, + curveSt: _propTypes.default.object.isRequired, + axesUnitsSt: _propTypes.default.object.isRequired, + updateXAxisAct: _propTypes.default.func.isRequired, + updateYAxisAct: _propTypes.default.func.isRequired +}; +var _default = exports.default = (0, _reactRedux.connect)(mapStateToProps, mapDispatchToProps)((0, _withStyles.default)(styles)(ChangeAxes)); \ No newline at end of file diff --git a/dist/components/cmd_bar/r09_detector.js b/dist/components/cmd_bar/r09_detector.js new file mode 100644 index 00000000..51ad2152 --- /dev/null +++ b/dist/components/cmd_bar/r09_detector.js @@ -0,0 +1,107 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; +var _react = _interopRequireDefault(require("react")); +var _propTypes = _interopRequireDefault(require("prop-types")); +var _reactRedux = require("react-redux"); +var _classnames = _interopRequireDefault(require("classnames")); +var _redux = require("redux"); +var _material = require("@mui/material"); +var _withStyles = _interopRequireDefault(require("@mui/styles/withStyles")); +var _detector = require("../../actions/detector"); +var _format = _interopRequireDefault(require("../../helpers/format")); +var _common = require("./common"); +var _list_detectors = require("../../constants/list_detectors"); +var _jsxRuntime = require("react/jsx-runtime"); +/* eslint-disable prefer-object-spread, react/jsx-one-expression-per-line, +react/function-component-definition */ + +const styles = () => Object.assign({ + fieldShift: { + width: 160 + }, + fieldLayout: { + width: 100 + } +}, _common.commonStyle); +const detectorSelect = (classes, detectorSt, curveSt, layoutSt, updateDetectorAct) => { + if (!_format.default.isSECLayout(layoutSt)) { + return /*#__PURE__*/(0, _jsxRuntime.jsx)("i", {}); + } + const { + curveIdx + } = curveSt; + const { + curves + } = detectorSt; + const getSelectedDetectorForCurve = (_detectorSt, targetCurveIdx) => { + const targetCurve = curves.find(curve => curve.curveIdx === targetCurveIdx); + return targetCurve ? targetCurve.selectedDetector : ''; + }; + const selectedDetector = getSelectedDetectorForCurve(detectorSt, curveIdx); + const onChange = e => updateDetectorAct({ + curveIdx, + selectedDetector: e.target.value + }); + return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_material.FormControl, { + className: (0, _classnames.default)(classes.fieldLayout), + children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_material.InputLabel, { + id: "select-detector-label", + className: (0, _classnames.default)(classes.selectLabel, 'select-sv-bar-label'), + children: "Detector" + }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_material.Select, { + labelId: "select-detector-label", + label: "Detector", + value: selectedDetector, + onChange: onChange, + className: (0, _classnames.default)(classes.selectInput, 'input-sv-bar-layout'), + children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_material.MenuItem, { + value: "", + children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: (0, _classnames.default)(classes.txtOpt, 'option-sv-bar-layout') + }) + }), _list_detectors.LIST_DETECTORS.map(item => /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.MenuItem, { + value: item, + children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: (0, _classnames.default)(classes.txtOpt, 'option-sv-bar-layout'), + children: item.name + }) + }))] + })] + }); +}; +const Detector = _ref => { + let { + classes, + detectorSt, + curveSt, + layoutSt, + updateDetectorAct + } = _ref; + return /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: classes.groupRight, + children: detectorSelect(classes, detectorSt, curveSt, layoutSt, updateDetectorAct) + }); +}; +const mapStateToProps = (state, _props) => ( +// eslint-disable-line +{ + detectorSt: state.detector, + curveSt: state.curve, + layoutSt: state.layout +}); +const mapDispatchToProps = dispatch => (0, _redux.bindActionCreators)({ + updateDetectorAct: _detector.updateDetector +}, dispatch); +Detector.propTypes = { + classes: _propTypes.default.object.isRequired, + layoutSt: _propTypes.default.string.isRequired, + curveSt: _propTypes.default.object.isRequired, + updateDetectorAct: _propTypes.default.func.isRequired, + detectorSt: _propTypes.default.object.isRequired +}; +var _default = exports.default = (0, _reactRedux.connect)(mapStateToProps, mapDispatchToProps)((0, _withStyles.default)(styles)(Detector)); \ No newline at end of file diff --git a/dist/components/cmd_bar/tri_btn.js b/dist/components/cmd_bar/tri_btn.js new file mode 100644 index 00000000..64800f48 --- /dev/null +++ b/dist/components/cmd_bar/tri_btn.js @@ -0,0 +1,131 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; +var _react = _interopRequireDefault(require("react")); +var _reactRedux = require("react-redux"); +var _redux = require("redux"); +var _classnames = _interopRequireDefault(require("classnames")); +var _propTypes = _interopRequireDefault(require("prop-types")); +var _styles = require("@mui/styles"); +var _Tooltip = _interopRequireDefault(require("@mui/material/Tooltip")); +var _cfg = _interopRequireDefault(require("../../helpers/cfg")); +var _common = require("./common"); +var _jsxRuntime = require("react/jsx-runtime"); +/* eslint-disable prefer-object-spread */ + +const styles = () => Object.assign({ + btnYes: { + color: 'green' + }, + btnNo: { + color: 'red' + }, + btnTxtConfirm: { + fontFamily: 'Helvetica', + fontSize: 12 + } +}, _common.commonStyle); +class TriBtn extends _react.default.Component { + constructor(props) { + super(props); + this.state = { + toggled: false + }; + this.onToggle = this.onToggle.bind(this); + this.renderStageOne = this.renderStageOne.bind(this); + this.renderStageTwo = this.renderStageTwo.bind(this); + } + onToggle(e) { + e.stopPropagation(); + e.preventDefault(); + const { + toggled + } = this.state; + this.setState({ + toggled: !toggled + }); + } + renderStageOne() { + const { + content, + layoutSt, + children, + isClearAllDisabled + } = this.props; + const { + tp + } = content; + const title = /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: "txt-sv-tp", + children: tp + }); + return /*#__PURE__*/(0, _jsxRuntime.jsx)(_Tooltip.default, { + title: title, + children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_common.MuButton, { + className: (0, _classnames.default)('btn-sv-bar-one'), + disabled: isClearAllDisabled === false ? false : _cfg.default.btnCmdMpy(layoutSt) && _cfg.default.btnCmdIntg(layoutSt), + onClick: this.onToggle, + children: children + }) + }) + }); + } + renderStageTwo() { + const { + classes, + layoutSt, + cb + } = this.props; + const onExec = e => { + cb(); + this.onToggle(e); + }; + return /*#__PURE__*/(0, _jsxRuntime.jsxs)("span", { + disabled: _cfg.default.btnCmdMpy(layoutSt) && _cfg.default.btnCmdIntg(layoutSt), + children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: (0, _classnames.default)(classes.txtLabel, 'txt-sv-bar-desc'), + children: "Delete ALL?" + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_common.MuButton, { + className: (0, _classnames.default)('btn-sv-bar-yes'), + onClick: onExec, + children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: (0, _classnames.default)(classes.txt, classes.btnYes, 'txt-sv-bar-yes'), + children: "Y" + }) + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_common.MuButton, { + className: (0, _classnames.default)('btn-sv-bar-no'), + onClick: this.onToggle, + children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: (0, _classnames.default)(classes.txt, classes.btnNo, 'txt-sv-bar-no'), + children: "N" + }) + })] + }); + } + render() { + const { + toggled + } = this.state; + return !toggled ? this.renderStageOne() : this.renderStageTwo(); + } +} +const mapStateToProps = (state, props) => ( +// eslint-disable-line +{ + layoutSt: state.layout +}); +const mapDispatchToProps = dispatch => (0, _redux.bindActionCreators)({}, dispatch); +TriBtn.propTypes = { + classes: _propTypes.default.object.isRequired, + layoutSt: _propTypes.default.string.isRequired, + content: _propTypes.default.object.isRequired, + cb: _propTypes.default.func.isRequired, + children: _propTypes.default.node.isRequired, + isClearAllDisabled: _propTypes.default.bool.isRequired +}; +var _default = exports.default = (0, _reactRedux.connect)(mapStateToProps, mapDispatchToProps)((0, _styles.withStyles)(styles)(TriBtn)); \ No newline at end of file diff --git a/dist/components/common/chem.js b/dist/components/common/chem.js new file mode 100644 index 00000000..7a15e0be --- /dev/null +++ b/dist/components/common/chem.js @@ -0,0 +1,115 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; +/* eslint-disable */ + +const SmaToSvg = sma => { + switch (sma) { + case 'C-,:O': + return ' O '; + case 'C-,:C(=O)-,:O-,:C': + return ' O O '; + case 'C-,:O-,:c': + return ' O '; + case 'c-,:[Cl]': + return ' Cl '; + case 'c:,-[n&H1]:,-c': + return ' N '; + case 'c-,:O': + return ' O '; + case 'C-,:[Cl]': + return ' Cl '; + case 'C-,:C(-,:C)=O': + return ' O '; + case 'c-,:[N&+](=O)-,:[O&-]': + return ' N + O O - '; + case 'C-,:C=C': + return ' '; + case 'c-,:[Br]': + return ' Br '; + case 'C-,:O-,:C': + return ' O '; + case 'C-,:[Br]': + return ' Br '; + case 'C-,:C(-,:c)=O': + return ' O '; + case 'c-,:N': + return ' N '; + case 'C-,:F': + return ' F '; + case 'c-,:C(=O)-,:O-,:C': + return ' O O '; + case 'c:,-o:,-c': + return ' O '; + case 'C-,:C(=O)-,:O': + return ' O O '; + case 'c-,:F': + return ' F '; + case 'c=O': + return ' O '; + case 'C-,:N-,:C': + return ' N '; + case 'C-,:N(-,:C)-,:C': + return ' N '; + case 'C-,:N': + return ' N '; + case 'C-,:n(-,:c):,-c': + return ' N '; + case 'c-,:C(=O)-,:O': + return ' O O '; + case 'c-,:C=O': + return ' O '; + case 'C-,:C#N': + return ' N '; + case 'C-,:C=C-,:C': + return ' '; + case 'C-,:C(=O)-,:N-,:C': + return ' O N '; + case 'c-,:C#N': + return ' N '; + case 'C-,:C(=O)-,:N-,:c': + return ' O N '; + case 'C-,:C(-,:C)=C': + return ' '; + case 'c:,-s:,-c': + return ' S '; + case 'C-,:C#C-,:C': + return ' '; + case 'C#C-,:C': + return ' '; + case 'c-,:C(-,:c)=O': + return ' O '; + case 'C-,:C(-,:C)=C-,:C': + return ' '; + case 'c-,:N(-,:C)-,:C': + return ' N '; + case 'C-,:N-,:c': + return ' N '; + case 'C-,:O-,:C(-,:C)=O': + return ' O O '; + case 'c-,:O-,:C': + return ' O '; + case 'c:,-n:,-c': + return ' N '; + case 'C=C-,:C': + return ' '; + case 'c-,:C(-,:C)=O': + return ' O '; + case 'c:,-n(-,:c)-,:C': + return ' N '; + case 'C-,:N-,:C(-,:C)=O': + return ' N O '; + case 'c-,:N-,:C(-,:C)=O': + return ' N O '; + case 'C=C(-,:C)-,:C': + return ' '; + default: + return ' N.A. '; + } +}; + +/* eslint-enable */ +var _default = exports.default = SmaToSvg; \ No newline at end of file diff --git a/dist/components/common/comps.js b/dist/components/common/comps.js new file mode 100644 index 00000000..435b9d23 --- /dev/null +++ b/dist/components/common/comps.js @@ -0,0 +1,17 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.TabLabel = void 0; +var _react = _interopRequireDefault(require("react")); +var _classnames = _interopRequireDefault(require("classnames")); +var _jsxRuntime = require("react/jsx-runtime"); +const TabLabel = exports.TabLabel = function TabLabel(classes, label) { + let extClsName = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'txt-tab-label'; + return /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: (0, _classnames.default)(classes.tabLabel, extClsName), + children: label + }); +}; \ No newline at end of file diff --git a/dist/components/common/draw.js b/dist/components/common/draw.js new file mode 100644 index 00000000..deba70ef --- /dev/null +++ b/dist/components/common/draw.js @@ -0,0 +1,51 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.drawMain = exports.drawLabel = exports.drawDisplay = exports.drawDestroy = exports.drawArrowOnCurve = void 0; +const d3 = require('d3'); +const drawMain = (klass, w, h) => { + d3.select(klass).append('svg').attr('class', 'd3Svg').attr('preserveAspectRatio', 'xMinYMin meet').attr('viewBox', `0 0 ${w} ${h}`); +}; +exports.drawMain = drawMain; +const drawLabel = (klass, cLabel, xLabel, yLabel) => { + d3.select(klass).selectAll('.xLabel').text(xLabel); + d3.select(klass).selectAll('.yLabel').text(yLabel); + if (cLabel) { + d3.select(klass).selectAll('.mark-text').text(cLabel); + } +}; +exports.drawLabel = drawLabel; +const drawDisplay = (klass, isHidden) => { + if (isHidden) { + d3.select(klass).selectAll('svg').style('width', 0); + } else { + d3.select(klass).selectAll('svg').style('width', '100%'); + } +}; +exports.drawDisplay = drawDisplay; +const drawDestroy = klass => d3.select(`${klass} > *`).remove(); +exports.drawDestroy = drawDestroy; +const drawArrowOnCurve = (klass, isHidden) => { + if (isHidden) { + d3.select(klass).selectAll('marker').remove(); + } else { + d3.select(klass).selectAll('marker').remove(); + const arrowLeft = d3.select(klass).selectAll('defs').append('marker').attr('id', 'arrow-left').attr('viewBox', '0 0 10 10').attr('refX', 5).attr('refY', 5).attr('markerWidth', 6).attr('markerHeight', 6).attr('orient', 'auto').attr('fill', '#00AA0099'); + arrowLeft.append('path').attr('d', 'M 0 0 L 10 5 L 0 10 z'); + + // const arrowRight = d3.select(klass).selectAll('defs') + // .append('marker') + // .attr('id', 'arrow-right') + // .attr('viewBox', '0 0 10 10') + // .attr('refX', 5) + // .attr('refY', 5) + // .attr('markerWidth', 6) + // .attr('markerHeight', 6) + // .attr('orient', 'auto-start-reverse'); + // arrowRight.append('path') + // .attr('d', 'M 0 0 L 10 5 L 0 10 z'); + } +}; +exports.drawArrowOnCurve = drawArrowOnCurve; \ No newline at end of file diff --git a/dist/components/d3_line/index.js b/dist/components/d3_line/index.js new file mode 100644 index 00000000..177e2b9e --- /dev/null +++ b/dist/components/d3_line/index.js @@ -0,0 +1,234 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; +var _react = _interopRequireDefault(require("react")); +var _reactRedux = require("react-redux"); +var _redux = require("redux"); +var _propTypes = _interopRequireDefault(require("prop-types")); +var _chem = require("../../helpers/chem"); +var _manager = require("../../actions/manager"); +var _ui = require("../../actions/ui"); +var _line_focus = _interopRequireDefault(require("./line_focus")); +var _draw = require("../common/draw"); +var _list_ui = require("../../constants/list_ui"); +var _cyclic_voltammetry = require("../../actions/cyclic_voltammetry"); +var _jsxRuntime = require("react/jsx-runtime"); +/* eslint-disable no-mixed-operators */ + +const W = Math.round(window.innerWidth * 0.90 * 9 / 12); // ROI +const H = Math.round(window.innerHeight * 0.90 * 0.85); // ROI + +class ViewerLine extends _react.default.Component { + constructor(props) { + super(props); + const { + clickUiTargetAct, + selectUiSweepAct, + scrollUiWheelAct + } = props; + this.rootKlass = '.d3Line'; + this.focus = new _line_focus.default({ + W, + H, + clickUiTargetAct, + selectUiSweepAct, + scrollUiWheelAct + }); + this.normChange = this.normChange.bind(this); + } + componentDidMount() { + const { + seed, + peak, + cLabel, + xLabel, + yLabel, + feature, + freq, + comparisons, + tTrEndPts, + tSfPeaks, + editPeakSt, + layoutSt, + integationSt, + mtplySt, + sweepExtentSt, + isUiAddIntgSt, + isUiNoBrushSt, + isHidden, + wavelength, + axesUnitsSt, + resetAllAct + } = this.props; + (0, _draw.drawDestroy)(this.rootKlass); + if (!isHidden) { + resetAllAct(feature); + } + let xxLabel = xLabel; + let yyLabel = yLabel; + if (axesUnitsSt) { + const { + axes + } = axesUnitsSt; + const { + xUnit, + yUnit + } = axes[0]; + xxLabel = xUnit === '' ? xLabel : xUnit; + yyLabel = yUnit === '' ? yLabel : yUnit; + } + const filterSeed = seed; + const filterPeak = peak; + (0, _draw.drawMain)(this.rootKlass, W, H); + this.focus.create({ + filterSeed, + filterPeak, + freq, + comparisons, + tTrEndPts, + tSfPeaks, + editPeakSt, + layoutSt, + integationSt, + mtplySt, + sweepExtentSt, + isUiAddIntgSt, + isUiNoBrushSt, + wavelength + }); + (0, _draw.drawLabel)(this.rootKlass, cLabel, xxLabel, yyLabel); + (0, _draw.drawDisplay)(this.rootKlass, isHidden); + } + componentDidUpdate(prevProps) { + const { + seed, + peak, + cLabel, + xLabel, + yLabel, + freq, + comparisons, + tTrEndPts, + tSfPeaks, + editPeakSt, + layoutSt, + integationSt, + mtplySt, + sweepExtentSt, + isUiAddIntgSt, + isUiNoBrushSt, + isHidden, + wavelength, + axesUnitsSt + } = this.props; + this.normChange(prevProps); + let xxLabel = xLabel; + let yyLabel = yLabel; + if (axesUnitsSt) { + const { + axes + } = axesUnitsSt; + const { + xUnit, + yUnit + } = axes[0]; + xxLabel = xUnit === '' ? xLabel : xUnit; + yyLabel = yUnit === '' ? yLabel : yUnit; + } + const filterSeed = seed; + const filterPeak = peak; + this.focus.update({ + filterSeed, + filterPeak, + freq, + comparisons, + tTrEndPts, + tSfPeaks, + editPeakSt, + layoutSt, + integationSt, + mtplySt, + sweepExtentSt, + isUiAddIntgSt, + isUiNoBrushSt, + wavelength + }); + (0, _draw.drawLabel)(this.rootKlass, cLabel, xxLabel, yyLabel); + (0, _draw.drawDisplay)(this.rootKlass, isHidden); + } + componentWillUnmount() { + (0, _draw.drawDestroy)(this.rootKlass); + } + normChange(prevProps) { + const { + feature, + resetAllAct + } = this.props; + const oldFeature = prevProps.feature; + if (oldFeature !== feature) { + resetAllAct(feature); + } + } + render() { + return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", { + className: "d3Line" + }); + } +} +const mapStateToProps = (state, props) => ({ + seed: (0, _chem.Topic2Seed)(state, props), + peak: (0, _chem.Feature2Peak)(state, props), + freq: (0, _chem.ToFrequency)(state, props), + comparisons: (0, _chem.GetComparisons)(state, props), + tTrEndPts: (0, _chem.ToThresEndPts)(state, props), + tSfPeaks: (0, _chem.ToShiftPeaks)(state, props), + editPeakSt: state.editPeak.present, + layoutSt: state.layout, + integationSt: state.integration.present, + mtplySt: state.multiplicity.present, + sweepExtentSt: state.ui.sweepExtent, + isUiAddIntgSt: state.ui.sweepType === _list_ui.LIST_UI_SWEEP_TYPE.INTEGRATION_ADD, + isUiNoBrushSt: _list_ui.LIST_NON_BRUSH_TYPES.indexOf(state.ui.sweepType) < 0, + wavelength: state.wavelength, + axesUnitsSt: state.axesUnits +}); +const mapDispatchToProps = dispatch => (0, _redux.bindActionCreators)({ + resetAllAct: _manager.resetAll, + clickUiTargetAct: _ui.clickUiTarget, + selectUiSweepAct: _ui.selectUiSweep, + scrollUiWheelAct: _ui.scrollUiWheel, + addNewCylicVoltaPairPeakAct: _cyclic_voltammetry.addNewCylicVoltaPairPeak, + addCylicVoltaMaxPeakAct: _cyclic_voltammetry.addCylicVoltaMaxPeak, + addCylicVoltaMinPeakAct: _cyclic_voltammetry.addCylicVoltaMinPeak +}, dispatch); +ViewerLine.propTypes = { + seed: _propTypes.default.array.isRequired, + peak: _propTypes.default.array.isRequired, + freq: _propTypes.default.oneOfType([_propTypes.default.bool, _propTypes.default.number]).isRequired, + comparisons: _propTypes.default.array.isRequired, + cLabel: _propTypes.default.string.isRequired, + xLabel: _propTypes.default.string.isRequired, + yLabel: _propTypes.default.string.isRequired, + feature: _propTypes.default.object.isRequired, + tTrEndPts: _propTypes.default.array.isRequired, + tSfPeaks: _propTypes.default.array.isRequired, + editPeakSt: _propTypes.default.object.isRequired, + layoutSt: _propTypes.default.string.isRequired, + integationSt: _propTypes.default.object.isRequired, + mtplySt: _propTypes.default.object.isRequired, + sweepExtentSt: _propTypes.default.object.isRequired, + isUiAddIntgSt: _propTypes.default.bool.isRequired, + isUiNoBrushSt: _propTypes.default.bool.isRequired, + resetAllAct: _propTypes.default.func.isRequired, + clickUiTargetAct: _propTypes.default.func.isRequired, + selectUiSweepAct: _propTypes.default.func.isRequired, + scrollUiWheelAct: _propTypes.default.func.isRequired, + isHidden: _propTypes.default.bool.isRequired, + wavelength: _propTypes.default.object.isRequired, + axesUnitsSt: _propTypes.default.object.isRequired +}; +var _default = exports.default = (0, _reactRedux.connect)(mapStateToProps, mapDispatchToProps)(ViewerLine); \ No newline at end of file diff --git a/dist/components/d3_line/line_focus.js b/dist/components/d3_line/line_focus.js new file mode 100644 index 00000000..554587a9 --- /dev/null +++ b/dist/components/d3_line/line_focus.js @@ -0,0 +1,684 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; +var _init = require("../../helpers/init"); +var _mount = require("../../helpers/mount"); +var _brush = _interopRequireDefault(require("../../helpers/brush")); +var _compass = require("../../helpers/compass"); +var _converter = require("../../helpers/converter"); +var _focus = require("../../helpers/focus"); +var _integration = require("../../helpers/integration"); +var _multiplicity_calc = require("../../helpers/multiplicity_calc"); +var _format = _interopRequireDefault(require("../../helpers/format")); +var _cfg = _interopRequireDefault(require("../../helpers/cfg")); +var _list_layout = require("../../constants/list_layout"); +var _calc = require("../../helpers/calc"); +/* eslint-disable prefer-object-spread, no-mixed-operators */ + +const d3 = require('d3'); +class LineFocus { + constructor(props) { + const { + W, + H, + clickUiTargetAct, + selectUiSweepAct, + scrollUiWheelAct + } = props; + this.jcampIdx = 0; + this.rootKlass = '.d3Line'; + this.margin = { + t: 5, + b: 40, + l: 60, + r: 5 + }; + this.w = W - this.margin.l - this.margin.r; + this.h = H - this.margin.t - this.margin.b; + this.clickUiTargetAct = clickUiTargetAct; + this.selectUiSweepAct = selectUiSweepAct; + this.scrollUiWheelAct = scrollUiWheelAct; + this.brush = d3.brush(); + this.brushX = d3.brushX(); + this.axis = null; + this.path = null; + this.thresLineUp = null; + this.thresLineDw = null; + this.grid = null; + this.tags = null; + this.ref = null; + this.ccPattern = null; + this.data = []; + this.dataPks = []; + this.tTrEndPts = null; + this.tSfPeaks = null; + this.root = null; + this.svg = null; + this.axisCall = (0, _init.InitAxisCall)(5); + this.pathCall = null; + this.tip = null; + this.factor = 0.125; + this.currentExtent = null; + this.shouldUpdate = {}; + this.freq = false; + this.layout = _list_layout.LIST_LAYOUT.H1; + this.getShouldUpdate = this.getShouldUpdate.bind(this); + this.resetShouldUpdate = this.resetShouldUpdate.bind(this); + this.setTip = this.setTip.bind(this); + this.setDataParams = this.setDataParams.bind(this); + this.create = this.create.bind(this); + this.update = this.update.bind(this); + this.setConfig = this.setConfig.bind(this); + this.drawLine = this.drawLine.bind(this); + this.drawThres = this.drawThres.bind(this); + this.drawGrid = this.drawGrid.bind(this); + this.drawAUC = this.drawAUC.bind(this); + this.drawPeaks = this.drawPeaks.bind(this); + this.drawRef = this.drawRef.bind(this); + this.drawInteg = this.drawInteg.bind(this); + this.drawMtply = this.drawMtply.bind(this); + this.drawComparisons = this.drawComparisons.bind(this); + this.onClickTarget = this.onClickTarget.bind(this); + this.mergedPeaks = this.mergedPeaks.bind(this); + this.isFirefox = typeof InstallTrigger !== 'undefined'; + this.wavelength = null; + } + getShouldUpdate(nextEpSt, nextItSt, nextMySt) { + const { + prevXt, + prevYt, + prevEpSt, + prevLySt, + prevItSt, + prevMySt, + prevTePt, + prevDtPk, + prevSfPk, + prevData + } = this.shouldUpdate; + const { + xt, + yt + } = (0, _compass.TfRescale)(this); + const sameXY = xt(1.1) === prevXt && prevYt === yt(1.1); + const sameEpSt = prevEpSt === nextEpSt; + const sameLySt = prevLySt === this.layout; + const sameItSt = prevItSt === nextItSt; + const sameMySt = prevMySt === nextMySt; + const sameTePt = prevTePt === this.tTrEndPts.length; + const sameDtPk = prevDtPk === this.dataPks.length; + const sameSfPk = JSON.stringify(prevSfPk) === JSON.stringify(this.tSfPeaks); + const sameData = prevData === this.data.length; + const sameRef = prevEpSt.prevOffset === nextEpSt.prevOffset; + this.shouldUpdate = Object.assign({}, this.shouldUpdate, { + sameXY, + sameEpSt, + sameLySt, + sameItSt, + sameMySt, + // eslint-disable-line + sameTePt, + sameDtPk, + sameSfPk, + sameData, + sameRef // eslint-disable-line + }); + } + resetShouldUpdate(prevEpSt, prevItSt, prevMySt) { + const { + xt, + yt + } = (0, _compass.TfRescale)(this); + const prevXt = xt(1.1); + const prevYt = yt(1.1); + const prevTePt = this.tTrEndPts.length; + const prevDtPk = this.dataPks.length; + const prevSfPk = this.tSfPeaks; + const prevData = this.data.length; + const prevLySt = this.layout; + this.shouldUpdate = Object.assign({}, this.shouldUpdate, { + prevXt, + prevYt, + prevEpSt, + prevLySt, + prevItSt, + prevMySt, + // eslint-disable-line + prevTePt, + prevDtPk, + prevSfPk, + prevData // eslint-disable-line + }); + } + setTip() { + this.tip = (0, _init.InitTip)(); + this.root.call(this.tip); + } + setDataParams(data, peaks, tTrEndPts, tSfPeaks, freq, layout, wavelength) { + this.data = [...data]; + this.dataPks = [...peaks]; + this.tTrEndPts = tTrEndPts; + this.tSfPeaks = tSfPeaks; + this.freq = freq; + this.layout = layout; + this.wavelength = wavelength; + } + updatePathCall(xt, yt) { + this.pathCall = d3.line().x(d => xt(d.x)).y(d => yt(d.y)); + } + setConfig(sweepExtentSt) { + // Domain Calculate + let { + xExtent, + yExtent + } = sweepExtentSt || { + xExtent: false, + yExtent: false + }; + if (!xExtent || !yExtent) { + const xes = d3.extent(this.data, d => d.x).sort((a, b) => a - b); + xExtent = { + xL: xes[0], + xU: xes[1] + }; + const btm = d3.min(this.data, d => d.y); + const top = d3.max(this.data, d => d.y); + const height = top - btm; + yExtent = { + yL: btm - this.factor * height, + yU: top + this.factor * height + }; + } + this.scales.x.domain([xExtent.xL, xExtent.xU]); + this.scales.y.domain([yExtent.yL, yExtent.yU]); + + // rescale for zoom + const { + xt, + yt + } = (0, _compass.TfRescale)(this); + + // Axis Call + this.axisCall.x.scale(xt); + this.axisCall.y.scale(yt); + this.currentExtent = { + xExtent, + yExtent + }; + } + drawLine() { + const { + sameXY, + sameRef, + sameSfPk + } = this.shouldUpdate; + if (sameXY && sameRef && sameSfPk) return; + const { + xt, + yt + } = (0, _compass.TfRescale)(this); + this.updatePathCall(xt, yt); + this.path.attr('d', this.pathCall(this.data)); + } + drawThres() { + if (this.tTrEndPts.length > 0) { + this.thresLineUp.attr('d', this.pathCall(this.tTrEndPts)); + this.thresLineUp.attr('visibility', 'visible'); + const [left, right] = this.tTrEndPts; + const dwMirrorEndPts = [Object.assign({}, left, { + y: -left.y + }), Object.assign({}, right, { + y: -right.y + })]; + this.thresLineDw.attr('d', this.pathCall(dwMirrorEndPts)); + this.thresLineDw.attr('visibility', 'visible'); + } else { + this.thresLineUp.attr('visibility', 'hidden'); + this.thresLineDw.attr('visibility', 'hidden'); + } + } + drawGrid() { + const { + sameXY, + sameSfPk + } = this.shouldUpdate; + if (sameXY && sameSfPk) return; + this.grid.x.call(this.axisCall.x.tickSize(-this.h, 0, 0)).selectAll('line').attr('stroke', '#ddd').attr('stroke-opacity', 0.6).attr('fill', 'none'); + this.grid.y.call(this.axisCall.y.tickSize(-this.w, 0, 0)).selectAll('line').attr('stroke', '#ddd').attr('stroke-opacity', 0.6).attr('fill', 'none'); + } + onClickTarget(event, data) { + event.stopPropagation(); + event.preventDefault(); + const onPeak = true; + this.clickUiTargetAct(data, onPeak); + } + mergedPeaks(editPeakSt) { + if (!editPeakSt) return this.dataPks; + this.dataPks = (0, _converter.PksEdit)(this.dataPks, editPeakSt); + return this.dataPks; + } + drawAUC(stack) { + const { + xt, + yt + } = (0, _compass.TfRescale)(this); + const auc = this.tags.aucPath.selectAll('path').data(stack); + auc.exit().attr('class', 'exit').remove(); + const integCurve = border => { + const { + xL, + xU + } = border; + const ps = this.data.filter(d => d.x > xL && d.x < xU); + if (!ps[0]) return null; + const point1 = ps[0]; + const point2 = ps[ps.length - 1]; + const slope = (0, _calc.calcSlope)(point1.x, point1.y, point2.x, point2.y); + let lastDY = point1.y; + return d3.area().x(d => xt(d.x)).y0((d, index) => { + if (index > 0) { + const lastD = ps[index - 1]; + const y = slope * (d.x - lastD.x) + lastDY; + lastDY = y; + return yt(y); + } + return yt(0); + }).y1(d => yt(d.y))(ps); + }; + auc.enter().append('path').attr('class', 'auc').attr('fill', 'red').attr('stroke', 'none').attr('fill-opacity', 0.2).attr('stroke-width', 2).merge(auc).attr('d', d => integCurve(d)).attr('id', d => `auc${(0, _focus.itgIdTag)(d)}`).on('mouseover', (event, d) => { + d3.select(`#auc${(0, _focus.itgIdTag)(d)}`).attr('stroke', 'blue'); + d3.select(`#auc${(0, _focus.itgIdTag)(d)}`).attr('stroke', 'blue'); + d3.select(`#auc${(0, _focus.itgIdTag)(d)}`).style('fill', 'blue'); + }).on('mouseout', (event, d) => { + d3.select(`#auc${(0, _focus.itgIdTag)(d)}`).attr('stroke', 'none'); + d3.select(`#auc${(0, _focus.itgIdTag)(d)}`).style('fill', 'red'); + d3.select(`#auc${(0, _focus.itgIdTag)(d)}`).style('fill-opacity', 0.2); + }).on('click', (event, d) => this.onClickTarget(event, d)); + } + drawPeaks(editPeakSt) { + const { + sameXY, + sameEpSt, + sameDtPk, + sameSfPk + } = this.shouldUpdate; + if (!_format.default.isCyclicVoltaLayout(this.layout) && sameXY && sameEpSt && sameDtPk && sameSfPk) return; + + // rescale for zoom + const { + xt, + yt + } = (0, _compass.TfRescale)(this); + const dPks = this.mergedPeaks(editPeakSt); + const mpp = this.tags.pPath.selectAll('path').data(dPks); + mpp.exit().attr('class', 'exit').remove(); + const linePath = [{ + x: -0.5, + y: 10 + }, { + x: -0.5, + y: -20 + }, { + x: 0.5, + y: -20 + }, { + x: 0.5, + y: 10 + }]; + // const faktor = layoutSt === LIST_LAYOUT.IR ? -1 : 1; + const lineSymbol = d3.line().x(d => d.x).y(d => d.y)(linePath); + 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) => { + d3.select(`#mpp${Math.round(1000 * d.x)}`).attr('stroke-opacity', '1.0'); + d3.select(`#bpt${Math.round(1000 * d.x)}`).style('fill', 'blue'); + const tipParams = { + d, + layout: this.layout + }; + this.tip.show(tipParams, event.target); + }).on('mouseout', (event, d) => { + d3.select(`#mpp${Math.round(1000 * d.x)}`).attr('stroke-opacity', '0.0'); + d3.select(`#bpt${Math.round(1000 * d.x)}`).style('fill', 'red'); + const tipParams = { + d, + layout: this.layout + }; + this.tip.hide(tipParams, event.target); + }).on('click', (event, d) => this.onClickTarget(event, d)); + const ignoreRef = _format.default.isHplcUvVisLayout(this.layout); + if (ignoreRef) { + const bpTxt = this.tags.bpTxt.selectAll('text').data(dPks); + bpTxt.exit().attr('class', 'exit').remove(); + 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)); + } + } + drawInteg(integationSt) { + const { + sameXY, + sameLySt, + sameItSt, + sameData + } = this.shouldUpdate; + if (sameXY && sameLySt && sameItSt && sameData) return; + const { + selectedIdx, + integrations + } = integationSt; + const selectedIntegration = integrations[selectedIdx]; + const { + stack, + refArea, + refFactor, + shift + } = selectedIntegration; + const isDisable = _cfg.default.btnCmdIntg(this.layout); + const ignoreRef = _format.default.isHplcUvVisLayout(this.layout); + const itgs = isDisable ? [] : stack; + const igbp = this.tags.igbPath.selectAll('path').data(itgs); + igbp.exit().attr('class', 'exit').remove(); + const igcp = this.tags.igcPath.selectAll('path').data(itgs); + igcp.exit().attr('class', 'exit').remove(); + const igtp = this.tags.igtPath.selectAll('text').data(itgs); + igtp.exit().attr('class', 'exit').remove(); + if (itgs.length === 0 || isDisable) { + // remove drawn area under curve + const auc = this.tags.aucPath.selectAll('path').data(stack); + auc.exit().attr('class', 'exit').remove(); + auc.merge(auc); + return; + } + if (ignoreRef) { + this.drawAUC(stack); + } else { + // rescale for zoom + const { + xt + } = (0, _compass.TfRescale)(this); + const dh = 50; + const integBar = data => d3.line()([[xt(data.xL - shift), dh], [xt(data.xL - shift), dh - 10], [xt(data.xL - shift), dh - 5], [xt(data.xU - shift), dh - 5], [xt(data.xU - shift), dh - 10], [xt(data.xU - shift), dh]]); + igbp.enter().append('path').attr('class', 'igbp').attr('fill', 'none').attr('stroke', '#228B22').attr('stroke-width', 2).merge(igbp).attr('id', d => `igbp${(0, _focus.itgIdTag)(d)}`).attr('d', d => integBar(d)).on('mouseover', (event, d) => { + d3.select(`#igbp${(0, _focus.itgIdTag)(d)}`).attr('stroke', 'blue'); + d3.select(`#igbc${(0, _focus.itgIdTag)(d)}`).attr('stroke', 'blue'); + d3.select(`#igtp${(0, _focus.itgIdTag)(d)}`).style('fill', 'blue'); + }).on('mouseout', (event, d) => { + d3.select(`#igbp${(0, _focus.itgIdTag)(d)}`).attr('stroke', '#228B22'); + d3.select(`#igbc${(0, _focus.itgIdTag)(d)}`).attr('stroke', '#228B22'); + d3.select(`#igtp${(0, _focus.itgIdTag)(d)}`).style('fill', '#228B22'); + }).on('click', (event, d) => this.onClickTarget(event, d)); + const integCurve = border => { + const { + xL, + xU + } = border; + const [nXL, nXU] = [xL - shift, xU - shift]; + const ps = this.data.filter(d => d.x > nXL && d.x < nXU); + const kMax = this.data[this.data.length - 1].k; + if (!ps[0]) return null; + const kRef = ps[0].k; + if (!this.reverseXAxis(this.layout)) { + return d3.line().x(d => xt(d.x)).y(d => 100 - (kRef - d.k) * 400 / kMax)(ps); + } + return d3.line().x(d => xt(d.x)).y(d => 300 - (d.k - kRef) * 400 / kMax)(ps); + }; + igcp.enter().append('path').attr('class', 'igcp').attr('fill', 'none').attr('stroke', '#228B22').attr('stroke-width', 2).merge(igcp).attr('id', d => `igbc${(0, _focus.itgIdTag)(d)}`).attr('d', d => integCurve(d)).on('mouseover', (event, d) => { + d3.select(`#igbp${(0, _focus.itgIdTag)(d)}`).attr('stroke', 'blue'); + d3.select(`#igbc${(0, _focus.itgIdTag)(d)}`).attr('stroke', 'blue'); + d3.select(`#igtp${(0, _focus.itgIdTag)(d)}`).style('fill', 'blue'); + }).on('mouseout', (event, d) => { + d3.select(`#igbp${(0, _focus.itgIdTag)(d)}`).attr('stroke', '#228B22'); + d3.select(`#igbc${(0, _focus.itgIdTag)(d)}`).attr('stroke', '#228B22'); + d3.select(`#igtp${(0, _focus.itgIdTag)(d)}`).style('fill', '#228B22'); + }).on('click', (event, d) => this.onClickTarget(event, d)); + igtp.enter().append('text').attr('class', 'igtp').attr('font-family', 'Helvetica').style('font-size', '12px').attr('fill', '#228B22').style('text-anchor', 'middle').merge(igtp).attr('id', d => `igtp${(0, _focus.itgIdTag)(d)}`).text(d => (0, _integration.calcArea)(d, refArea, refFactor, ignoreRef)).attr('transform', d => `translate(${xt((d.xL + d.xU) / 2 - shift)}, ${dh - 12})`).on('mouseover', (event, d) => { + d3.select(`#igbp${(0, _focus.itgIdTag)(d)}`).attr('stroke', 'blue'); + d3.select(`#igbc${(0, _focus.itgIdTag)(d)}`).attr('stroke', 'blue'); + d3.select(`#igtp${(0, _focus.itgIdTag)(d)}`).style('fill', 'blue'); + }).on('mouseout', (event, d) => { + d3.select(`#igbp${(0, _focus.itgIdTag)(d)}`).attr('stroke', '#228B22'); + d3.select(`#igbc${(0, _focus.itgIdTag)(d)}`).attr('stroke', '#228B22'); + d3.select(`#igtp${(0, _focus.itgIdTag)(d)}`).style('fill', '#228B22'); + }).on('click', (event, d) => this.onClickTarget(event, d)); + } + } + drawMtply(mtplySt) { + const { + sameXY, + sameLySt, + sameMySt + } = this.shouldUpdate; + if (sameXY && sameLySt && sameMySt) return; + const { + selectedIdx, + multiplicities + } = mtplySt; + const selectedMulti = multiplicities[selectedIdx]; + const { + stack, + smExtext, + shift + } = selectedMulti; + const mpys = stack; + const isDisable = _cfg.default.btnCmdMpy(this.layout); + if (mpys === 0 || isDisable) return; + // rescale for zoom + const { + xt + } = (0, _compass.TfRescale)(this); + const mpyb = this.tags.mpybPath.selectAll('path').data(mpys); + mpyb.exit().attr('class', 'exit').remove(); + const mpyt1 = this.tags.mpyt1Path.selectAll('text').data(mpys); + mpyt1.exit().attr('class', 'exit').remove(); + const mpyt2 = this.tags.mpyt2Path.selectAll('text').data(mpys); + mpyt2.exit().attr('class', 'exit').remove(); + let mPeaks = mpys.map(m => { + const { + peaks, + xExtent + } = m; + return peaks.map(p => Object.assign({}, p, { + xExtent + })); + }); + mPeaks = [].concat(...mPeaks); + const mpyp = this.tags.mpypPath.selectAll('path').data(mPeaks); + mpyp.exit().attr('class', 'exit').remove(); + const height = this.h; + const dh = Math.abs(0.06 * height); + const mpyBar = data => d3.line()([[xt(data.xExtent.xL - shift), height - dh], [xt(data.xExtent.xL - shift), height - dh - 10], [xt(data.xExtent.xL - shift), height - dh - 5], [xt(data.xExtent.xU - shift), height - dh - 5], [xt(data.xExtent.xU - shift), height - dh - 10], [xt(data.xExtent.xU - shift), height - dh]]); + const mpyColor = d => { + const { + xL, + xU + } = d.xExtent; + return smExtext.xL === xL && smExtext.xU === xU ? 'purple' : '#DA70D6'; + }; + mpyb.enter().append('path').attr('class', 'mpyb').attr('fill', 'none').attr('stroke-width', 2).merge(mpyb).attr('stroke', d => mpyColor(d)).attr('id', d => `mpyb${(0, _focus.mpyIdTag)(d)}`).attr('d', d => mpyBar(d)).on('mouseover', (event, d) => { + d3.selectAll(`#mpyb${(0, _focus.mpyIdTag)(d)}`).attr('stroke', 'blue'); + d3.selectAll(`#mpyt1${(0, _focus.mpyIdTag)(d)}`).style('fill', 'blue'); + d3.selectAll(`#mpyt2${(0, _focus.mpyIdTag)(d)}`).style('fill', 'blue'); + d3.selectAll(`#mpyp${(0, _focus.mpyIdTag)(d)}`).attr('stroke', 'blue'); + }).on('mouseout', (event, d) => { + const dColor = mpyColor(d); + d3.selectAll(`#mpyb${(0, _focus.mpyIdTag)(d)}`).attr('stroke', dColor); + d3.selectAll(`#mpyt1${(0, _focus.mpyIdTag)(d)}`).style('fill', dColor); + d3.selectAll(`#mpyt2${(0, _focus.mpyIdTag)(d)}`).style('fill', dColor); + d3.selectAll(`#mpyp${(0, _focus.mpyIdTag)(d)}`).attr('stroke', dColor); + }).on('click', (event, d) => this.onClickTarget(event, d)); + mpyt1.enter().append('text').attr('class', 'mpyt1').attr('font-family', 'Helvetica').style('font-size', '12px').style('text-anchor', 'middle').merge(mpyt1).attr('fill', d => mpyColor(d)).attr('id', d => `mpyt1${(0, _focus.mpyIdTag)(d)}`).text(d => `${(0, _multiplicity_calc.calcMpyCenter)(d.peaks, shift, d.mpyType).toFixed(3)}`).attr('transform', d => `translate(${xt((d.xExtent.xL + d.xExtent.xU) / 2 - shift)}, ${height - dh + 12})`).on('mouseover', (event, d) => { + d3.selectAll(`#mpyb${(0, _focus.mpyIdTag)(d)}`).attr('stroke', 'blue'); + d3.selectAll(`#mpyt1${(0, _focus.mpyIdTag)(d)}`).style('fill', 'blue'); + d3.selectAll(`#mpyt2${(0, _focus.mpyIdTag)(d)}`).style('fill', 'blue'); + d3.selectAll(`#mpyp${(0, _focus.mpyIdTag)(d)}`).attr('stroke', 'blue'); + }).on('mouseout', (event, d) => { + const dColor = mpyColor(d); + d3.selectAll(`#mpyb${(0, _focus.mpyIdTag)(d)}`).attr('stroke', dColor); + d3.selectAll(`#mpyt1${(0, _focus.mpyIdTag)(d)}`).style('fill', dColor); + d3.selectAll(`#mpyt2${(0, _focus.mpyIdTag)(d)}`).style('fill', dColor); + d3.selectAll(`#mpyp${(0, _focus.mpyIdTag)(d)}`).attr('stroke', dColor); + }).on('click', (event, d) => this.onClickTarget(event, d)); + mpyt2.enter().append('text').attr('class', 'mpyt2').attr('font-family', 'Helvetica').style('font-size', '12px').style('text-anchor', 'middle').merge(mpyt2).attr('fill', d => mpyColor(d)).attr('id', d => `mpyt2${(0, _focus.mpyIdTag)(d)}`).text(d => `(${d.mpyType})`).attr('transform', d => `translate(${xt((d.xExtent.xL + d.xExtent.xU) / 2 - shift)}, ${height - dh + 24})`).on('mouseover', (event, d) => { + d3.selectAll(`#mpyb${(0, _focus.mpyIdTag)(d)}`).attr('stroke', 'blue'); + d3.selectAll(`#mpyt1${(0, _focus.mpyIdTag)(d)}`).style('fill', 'blue'); + d3.selectAll(`#mpyt2${(0, _focus.mpyIdTag)(d)}`).style('fill', 'blue'); + d3.selectAll(`#mpyp${(0, _focus.mpyIdTag)(d)}`).attr('stroke', 'blue'); + }).on('mouseout', (event, d) => { + const dColor = mpyColor(d); + d3.selectAll(`#mpyb${(0, _focus.mpyIdTag)(d)}`).attr('stroke', dColor); + d3.selectAll(`#mpyt1${(0, _focus.mpyIdTag)(d)}`).style('fill', dColor); + d3.selectAll(`#mpyt2${(0, _focus.mpyIdTag)(d)}`).style('fill', dColor); + d3.selectAll(`#mpyp${(0, _focus.mpyIdTag)(d)}`).attr('stroke', dColor); + }).on('click', (event, d) => this.onClickTarget(event, d)); + const mpypH = height - dh; + const mpypPath = pk => [{ + x: xt(pk.x - shift) - 0.5, + y: mpypH - 5 + }, { + x: xt(pk.x - shift) - 0.5, + y: mpypH - 20 + }, { + x: xt(pk.x - shift) + 0.5, + y: mpypH - 20 + }, { + x: xt(pk.x - shift) + 0.5, + y: mpypH - 5 + }]; + // const faktor = layoutSt === LIST_LAYOUT.IR ? -1 : 1; + const lineSymbol = d3.line().x(d => d.x).y(d => d.y); + mpyp.enter().append('path').attr('class', 'mpyp').attr('fill', 'none').merge(mpyp).attr('stroke', d => mpyColor(d)).attr('d', d => lineSymbol(mpypPath(d))).attr('id', d => `mpyp${(0, _focus.mpyIdTag)(d)}`).on('mouseover', (event, d) => { + d3.selectAll(`#mpyb${(0, _focus.mpyIdTag)(d)}`).attr('stroke', 'blue'); + d3.selectAll(`#mpyt1${(0, _focus.mpyIdTag)(d)}`).style('fill', 'blue'); + d3.selectAll(`#mpyt2${(0, _focus.mpyIdTag)(d)}`).style('fill', 'blue'); + d3.selectAll(`#mpyp${(0, _focus.mpyIdTag)(d)}`).attr('stroke', 'blue'); + }).on('mouseout', (event, d) => { + const dColor = mpyColor(d); + d3.selectAll(`#mpyb${(0, _focus.mpyIdTag)(d)}`).attr('stroke', dColor); + d3.selectAll(`#mpyt1${(0, _focus.mpyIdTag)(d)}`).style('fill', dColor); + d3.selectAll(`#mpyt2${(0, _focus.mpyIdTag)(d)}`).style('fill', dColor); + d3.selectAll(`#mpyp${(0, _focus.mpyIdTag)(d)}`).attr('stroke', dColor); + }).on('click', (event, d) => this.onClickTarget(event, d)); + } + drawRef() { + // rescale for zoom + const { + xt, + yt + } = (0, _compass.TfRescale)(this); + const ccp = this.ref.selectAll('path').data(this.tSfPeaks); + ccp.exit().attr('class', 'exit').remove(); + const linePath = [{ + x: -0.5, + y: 10 + }, { + x: -4, + y: -20 + }, { + x: 4, + y: -20 + }, { + x: 0.5, + y: 10 + }]; + const faktor = _format.default.isIrLayout(this.layout) ? -1 : 1; + const lineSymbol = d3.line().x(d => d.x).y(d => faktor * d.y)(linePath); + ccp.enter().append('path').attr('d', lineSymbol).attr('class', 'enter-ref').attr('fill', 'green').attr('fill-opacity', 0.8).merge(ccp).attr('transform', d => `translate(${xt(d.x)}, ${yt(d.y)})`); + } + drawComparisons(comparisons) { + d3.selectAll('.line-clip-compare').remove(); + if (!comparisons) return null; + comparisons.forEach((c, idx) => { + if (!c.show) return; + const path = (0, _mount.MountComparePath)(this, _format.default.compareColors(idx), idx); // #D5D8DC + path.attr('d', this.pathCall(c.data)); + }); + return null; + } + reverseXAxis(layoutSt) { + return [_list_layout.LIST_LAYOUT.UVVIS, _list_layout.LIST_LAYOUT.HPLC_UVVIS, _list_layout.LIST_LAYOUT.TGA, _list_layout.LIST_LAYOUT.DSC, _list_layout.LIST_LAYOUT.XRD, _list_layout.LIST_LAYOUT.CYCLIC_VOLTAMMETRY, _list_layout.LIST_LAYOUT.CDS, _list_layout.LIST_LAYOUT.DLS_ACF, _list_layout.LIST_LAYOUT.SEC, _list_layout.LIST_LAYOUT.GC, _list_layout.LIST_LAYOUT.EMISSIONS, _list_layout.LIST_LAYOUT.DLS_INTENSITY].indexOf(layoutSt) < 0; + } + create(_ref) { + let { + filterSeed, + filterPeak, + tTrEndPts, + tSfPeaks, + freq, + comparisons, + editPeakSt, + layoutSt, + integationSt, + mtplySt, + sweepExtentSt, + isUiAddIntgSt, + isUiNoBrushSt, + wavelength + } = _ref; + this.svg = d3.select('.d3Svg'); + (0, _mount.MountMainFrame)(this, 'focus'); + (0, _mount.MountClip)(this); + this.root = d3.select(this.rootKlass).selectAll('.focus-main'); + this.scales = (0, _init.InitScale)(this, this.reverseXAxis(layoutSt)); + this.setTip(); + this.setDataParams(filterSeed, filterPeak, tTrEndPts, tSfPeaks, freq, layoutSt, wavelength); + (0, _compass.MountCompass)(this); + this.axis = (0, _mount.MountAxis)(this); + this.path = (0, _mount.MountPath)(this, 'steelblue'); + [this.thresLineUp, this.thresLineDw] = (0, _mount.MountThresLine)(this, 'green'); + this.grid = (0, _mount.MountGrid)(this); + this.tags = (0, _mount.MountTags)(this); + this.ref = (0, _mount.MountRef)(this); + (0, _mount.MountAxisLabelX)(this); + (0, _mount.MountAxisLabelY)(this); + if (this.data && this.data.length > 0) { + this.setConfig(sweepExtentSt); + this.drawLine(); + this.drawThres(); + this.drawGrid(); + this.drawRef(); + this.drawPeaks(editPeakSt); + this.drawInteg(integationSt); + this.drawMtply(mtplySt); + this.drawComparisons(comparisons); + } + (0, _brush.default)(this, isUiAddIntgSt, isUiNoBrushSt); + this.resetShouldUpdate(editPeakSt, integationSt, mtplySt); + } + update(_ref2) { + let { + filterSeed, + filterPeak, + tTrEndPts, + tSfPeaks, + freq, + comparisons, + editPeakSt, + layoutSt, + integationSt, + mtplySt, + sweepExtentSt, + isUiAddIntgSt, + isUiNoBrushSt, + wavelength + } = _ref2; + this.root = d3.select(this.rootKlass).selectAll('.focus-main'); + this.scales = (0, _init.InitScale)(this, this.reverseXAxis(layoutSt)); + this.setDataParams(filterSeed, filterPeak, tTrEndPts, tSfPeaks, freq, layoutSt, wavelength); + if (this.data && this.data.length > 0) { + this.setConfig(sweepExtentSt); + this.getShouldUpdate(editPeakSt, integationSt, mtplySt); + this.drawLine(); + this.drawThres(); + this.drawGrid(); + this.drawRef(); + this.drawPeaks(editPeakSt); + this.drawInteg(integationSt); + this.drawMtply(mtplySt); + this.drawComparisons(comparisons); + } + (0, _brush.default)(this, isUiAddIntgSt, isUiNoBrushSt); + this.resetShouldUpdate(editPeakSt, integationSt, mtplySt); + } +} +var _default = exports.default = LineFocus; \ No newline at end of file diff --git a/dist/components/d3_multi/index.js b/dist/components/d3_multi/index.js new file mode 100644 index 00000000..fd796cdf --- /dev/null +++ b/dist/components/d3_multi/index.js @@ -0,0 +1,254 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; +var _react = _interopRequireDefault(require("react")); +var _reactRedux = require("react-redux"); +var _redux = require("redux"); +var _propTypes = _interopRequireDefault(require("prop-types")); +var _chem = require("../../helpers/chem"); +var _manager = require("../../actions/manager"); +var _ui = require("../../actions/ui"); +var _list_ui = require("../../constants/list_ui"); +var _cyclic_voltammetry = require("../../actions/cyclic_voltammetry"); +var _multi_focus = _interopRequireDefault(require("./multi_focus")); +var _draw = require("../common/draw"); +var _jsxRuntime = require("react/jsx-runtime"); +/* eslint-disable no-mixed-operators, react/require-default-props, +react/no-unused-prop-types */ + +const W = Math.round(window.innerWidth * 0.90 * 9 / 12); // ROI +const H = Math.round(window.innerHeight * 0.90 * 0.85); // ROI + +class ViewerMulti extends _react.default.Component { + constructor(props) { + super(props); + const { + entities, + clickUiTargetAct, + selectUiSweepAct, + scrollUiWheelAct + } = this.props; + this.rootKlass = '.d3Line'; + this.focus = new _multi_focus.default({ + W, + H, + entities, + clickUiTargetAct, + selectUiSweepAct, + scrollUiWheelAct + }); + this.normChange = this.normChange.bind(this); + } + componentDidMount() { + const { + curveSt, + seed, + peak, + cLabel, + xLabel, + yLabel, + feature, + tTrEndPts, + tSfPeaks, + editPeakSt, + layoutSt, + sweepExtentSt, + isUiNoBrushSt, + isHidden, + resetAllAct, + cyclicvoltaSt, + integationSt, + mtplySt, + axesUnitsSt + } = this.props; + (0, _draw.drawDestroy)(this.rootKlass); + resetAllAct(feature); + let xxLabel = xLabel; + let yyLabel = yLabel; + if (axesUnitsSt) { + const { + curveIdx + } = curveSt; + const { + axes + } = axesUnitsSt; + let selectedAxes = axes[curveIdx]; + if (!selectedAxes) { + selectedAxes = { + xUnit: '', + yUnit: '' + }; + } + const { + xUnit, + yUnit + } = selectedAxes; + xxLabel = xUnit === '' ? xLabel : xUnit; + yyLabel = yUnit === '' ? yLabel : yUnit; + } + const filterSeed = seed; + const filterPeak = peak; + (0, _draw.drawMain)(this.rootKlass, W, H); + this.focus.create({ + curveSt, + filterSeed, + filterPeak, + tTrEndPts, + tSfPeaks, + editPeakSt, + layoutSt, + sweepExtentSt, + isUiNoBrushSt, + cyclicvoltaSt, + integationSt, + mtplySt + }); + (0, _draw.drawLabel)(this.rootKlass, cLabel, xxLabel, yyLabel); + (0, _draw.drawDisplay)(this.rootKlass, isHidden); + (0, _draw.drawArrowOnCurve)(this.rootKlass, isHidden); + } + componentDidUpdate(prevProps) { + const { + entities, + curveSt, + seed, + peak, + cLabel, + xLabel, + yLabel, + tTrEndPts, + tSfPeaks, + editPeakSt, + layoutSt, + sweepExtentSt, + isUiNoBrushSt, + isHidden, + cyclicvoltaSt, + integationSt, + mtplySt, + axesUnitsSt + } = this.props; + this.normChange(prevProps); + let xxLabel = xLabel; + let yyLabel = yLabel; + if (axesUnitsSt) { + const { + curveIdx + } = curveSt; + const { + axes + } = axesUnitsSt; + let selectedAxes = axes[curveIdx]; + if (!selectedAxes) { + selectedAxes = { + xUnit: '', + yUnit: '' + }; + } + const { + xUnit, + yUnit + } = selectedAxes; + xxLabel = xUnit === '' ? xLabel : xUnit; + yyLabel = yUnit === '' ? yLabel : yUnit; + } + const filterSeed = seed; + const filterPeak = peak; + this.focus.update({ + entities, + curveSt, + filterSeed, + filterPeak, + tTrEndPts, + tSfPeaks, + editPeakSt, + layoutSt, + sweepExtentSt, + isUiNoBrushSt, + cyclicvoltaSt, + integationSt, + mtplySt + }); + (0, _draw.drawLabel)(this.rootKlass, cLabel, xxLabel, yyLabel); + (0, _draw.drawDisplay)(this.rootKlass, isHidden); + (0, _draw.drawArrowOnCurve)(this.rootKlass, isHidden); + } + componentWillUnmount() { + (0, _draw.drawDestroy)(this.rootKlass); + } + normChange(prevProps) { + const { + feature, + resetAllAct, + entities + } = this.props; + const oldEntities = prevProps.entities; + if (oldEntities !== entities) { + resetAllAct(feature); + } + } + render() { + return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", { + className: "d3Line" + }); + } +} +const mapStateToProps = (state, props) => ({ + curveSt: state.curve, + seed: (0, _chem.Topic2Seed)(state, props), + peak: (0, _chem.Feature2Peak)(state, props), + tTrEndPts: (0, _chem.ToThresEndPts)(state, props), + tSfPeaks: (0, _chem.ToShiftPeaks)(state, props), + editPeakSt: state.editPeak.present, + layoutSt: state.layout, + sweepExtentSt: state.ui.sweepExtent, + isUiNoBrushSt: _list_ui.LIST_NON_BRUSH_TYPES.indexOf(state.ui.sweepType) < 0, + cyclicvoltaSt: state.cyclicvolta, + maxminPeakSt: (0, _chem.Feature2MaxMinPeak)(state, props), + integationSt: state.integration.present, + mtplySt: state.multiplicity.present, + axesUnitsSt: state.axesUnits +}); +const mapDispatchToProps = dispatch => (0, _redux.bindActionCreators)({ + resetAllAct: _manager.resetAll, + clickUiTargetAct: _ui.clickUiTarget, + selectUiSweepAct: _ui.selectUiSweep, + scrollUiWheelAct: _ui.scrollUiWheel, + addNewCylicVoltaPairPeakAct: _cyclic_voltammetry.addNewCylicVoltaPairPeak, + addCylicVoltaMaxPeakAct: _cyclic_voltammetry.addCylicVoltaMaxPeak, + addCylicVoltaMinPeakAct: _cyclic_voltammetry.addCylicVoltaMinPeak +}, dispatch); +ViewerMulti.propTypes = { + curveSt: _propTypes.default.object.isRequired, + entities: _propTypes.default.array.isRequired, + seed: _propTypes.default.array.isRequired, + peak: _propTypes.default.array.isRequired, + xLabel: _propTypes.default.string.isRequired, + yLabel: _propTypes.default.string.isRequired, + feature: _propTypes.default.object.isRequired, + tTrEndPts: _propTypes.default.array.isRequired, + tSfPeaks: _propTypes.default.array.isRequired, + editPeakSt: _propTypes.default.object.isRequired, + layoutSt: _propTypes.default.string.isRequired, + integationSt: _propTypes.default.object.isRequired, + mtplySt: _propTypes.default.object.isRequired, + sweepExtentSt: _propTypes.default.object.isRequired, + isUiNoBrushSt: _propTypes.default.bool.isRequired, + resetAllAct: _propTypes.default.func.isRequired, + clickUiTargetAct: _propTypes.default.func.isRequired, + selectUiSweepAct: _propTypes.default.func.isRequired, + scrollUiWheelAct: _propTypes.default.func.isRequired, + isHidden: _propTypes.default.bool, + cyclicvoltaSt: _propTypes.default.object.isRequired, + maxminPeakSt: _propTypes.default.object, + addNewCylicVoltaPairPeakAct: _propTypes.default.func.isRequired, + addCylicVoltaMaxPeakAct: _propTypes.default.func.isRequired, + addCylicVoltaMinPeakAct: _propTypes.default.func.isRequired, + cLabel: _propTypes.default.string, + axesUnitsSt: _propTypes.default.object.isRequired +}; +var _default = exports.default = (0, _reactRedux.connect)(mapStateToProps, mapDispatchToProps)(ViewerMulti); \ No newline at end of file diff --git a/dist/components/d3_multi/multi_focus.js b/dist/components/d3_multi/multi_focus.js new file mode 100644 index 00000000..6ae38d83 --- /dev/null +++ b/dist/components/d3_multi/multi_focus.js @@ -0,0 +1,909 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; +var _init = require("../../helpers/init"); +var _mount = require("../../helpers/mount"); +var _converter = require("../../helpers/converter"); +var _brush = _interopRequireDefault(require("../../helpers/brush")); +var _compass = require("../../helpers/compass"); +var _list_layout = require("../../constants/list_layout"); +var _format = _interopRequireDefault(require("../../helpers/format")); +var _chem = require("../../helpers/chem"); +var _cfg = _interopRequireDefault(require("../../helpers/cfg")); +var _focus = require("../../helpers/focus"); +var _integration = require("../../helpers/integration"); +var _multiplicity_calc = require("../../helpers/multiplicity_calc"); +var _calc = require("../../helpers/calc"); +/* eslint-disable no-unused-vars, prefer-object-spread, no-mixed-operators, +no-unneeded-ternary, arrow-body-style, max-len */ + +const d3 = require('d3'); +class MultiFocus { + constructor(props) { + const { + W, + H, + clickUiTargetAct, + selectUiSweepAct, + scrollUiWheelAct, + entities + } = props; + this.entities = entities; + this.jcampIdx = 0; + this.isShowAllCurves = false; + this.rootKlass = '.d3Line'; + this.margin = { + t: 5, + b: 40, + l: 60, + r: 5 + }; + this.w = W - this.margin.l - this.margin.r; + this.h = H - this.margin.t - this.margin.b; + this.clickUiTargetAct = clickUiTargetAct; + this.selectUiSweepAct = selectUiSweepAct; + this.scrollUiWheelAct = scrollUiWheelAct; + this.brush = d3.brush(); + this.brushX = d3.brushX(); + this.axis = null; + this.path = null; + this.thresLineUp = null; + this.thresLineDw = null; + this.grid = null; + this.tags = null; + this.ref = null; + this.data = []; + this.otherLineData = []; + this.pathColor = 'steelblue'; + this.dataPks = []; + this.dataPeckers = []; + this.tTrEndPts = null; + this.tSfPeaks = null; + this.root = null; + this.svg = null; + this.axisCall = (0, _init.InitAxisCall)(5); + this.pathCall = null; + this.tip = null; + this.factor = 0.125; + this.currentExtent = null; + this.shouldUpdate = {}; + // this.freq = false; + this.layout = _list_layout.LIST_LAYOUT.CYCLIC_VOLTAMMETRY; + this.getShouldUpdate = this.getShouldUpdate.bind(this); + this.resetShouldUpdate = this.resetShouldUpdate.bind(this); + this.setTip = this.setTip.bind(this); + this.setDataParams = this.setDataParams.bind(this); + this.create = this.create.bind(this); + this.update = this.update.bind(this); + this.setConfig = this.setConfig.bind(this); + this.drawLine = this.drawLine.bind(this); + this.drawThres = this.drawThres.bind(this); + this.drawOtherLines = this.drawOtherLines.bind(this); + this.drawGrid = this.drawGrid.bind(this); + this.drawPeaks = this.drawPeaks.bind(this); + this.drawRef = this.drawRef.bind(this); + this.drawInteg = this.drawInteg.bind(this); + this.drawMtply = this.drawMtply.bind(this); + this.drawAUC = this.drawAUC.bind(this); + this.onClickTarget = this.onClickTarget.bind(this); + this.mergedPeaks = this.mergedPeaks.bind(this); + this.setDataPecker = this.setDataPecker.bind(this); + this.drawPeckers = this.drawPeckers.bind(this); + this.onClickPecker = this.onClickPecker.bind(this); + this.isFirefox = typeof InstallTrigger !== 'undefined'; + this.cyclicvoltaSt = null; + } + getShouldUpdate(nextEpSt) { + const { + prevXt, + prevYt, + prevEpSt, + prevLySt, + prevTePt, + prevDtPk, + prevSfPk, + prevData + } = this.shouldUpdate; + const { + xt, + yt + } = (0, _compass.TfRescale)(this); + const sameXY = xt(1.1) === prevXt && prevYt === yt(1.1); + const sameEpSt = prevEpSt === nextEpSt; + const sameLySt = prevLySt === this.layout; + const sameTePt = prevTePt === this.tTrEndPts.length; + const sameDtPk = prevDtPk === this.dataPks.length; + const sameSfPk = JSON.stringify(prevSfPk) === JSON.stringify(this.tSfPeaks); + const sameData = prevData === this.data.length; + this.shouldUpdate = Object.assign({}, this.shouldUpdate, { + sameXY, + sameEpSt, + sameLySt, + // eslint-disable-line + sameTePt, + sameDtPk, + sameSfPk, + sameData // eslint-disable-line + }); + } + resetShouldUpdate(prevEpSt) { + const { + xt, + yt + } = (0, _compass.TfRescale)(this); + const prevXt = xt(1.1); + const prevYt = yt(1.1); + const prevTePt = this.tTrEndPts.length; + const prevDtPk = this.dataPks.length; + const prevSfPk = this.tSfPeaks; + const prevData = this.data.length; + const prevLySt = this.layout; + this.shouldUpdate = Object.assign({}, this.shouldUpdate, { + prevXt, + prevYt, + prevEpSt, + prevLySt, + // eslint-disable-line + prevTePt, + prevDtPk, + prevSfPk, + prevData // eslint-disable-line + }); + } + setTip() { + this.tip = (0, _init.InitTip)(); + this.root.call(this.tip); + } + setDataParams(filterSeed, peaks, tTrEndPts, tSfPeaks, layout, cyclicvoltaSt) { + let jcampIdx = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : 0; + this.data = []; + this.otherLineData = []; + let filterSubLayoutValue = null; + this.entities.forEach((entry, idx) => { + const { + topic, + feature, + color + } = entry; + const offset = (0, _chem.GetCyclicVoltaPreviousShift)(cyclicvoltaSt, jcampIdx); + let currData = (0, _chem.convertTopic)(topic, layout, feature, offset); + if (idx === jcampIdx) { + if (!_format.default.isCyclicVoltaLayout(layout)) { + currData = filterSeed; + } + this.data = [...currData]; + this.pathColor = color; + filterSubLayoutValue = _format.default.isSECLayout(layout) ? feature.xUnit : feature.yUnit; + } else { + const filterValue = _format.default.isSECLayout(layout) ? feature.xUnit : feature.yUnit; + this.otherLineData.push({ + data: currData, + color, + filterSublayout: filterValue + }); + } + }); + if (_format.default.isSECLayout(layout) || _format.default.isGCLayout(layout)) { + this.otherLineData = this.otherLineData.filter(data => { + return data.filterSublayout === filterSubLayoutValue; + }); + } + if (this.jcampIdx === jcampIdx) { + this.dataPks = [...peaks]; + } else { + this.dataPks = peaks; + } + this.tTrEndPts = tTrEndPts; + this.tSfPeaks = tSfPeaks; + this.layout = layout; + this.cyclicvoltaSt = cyclicvoltaSt; + this.jcampIdx = jcampIdx; + } + updatePathCall(xt, yt) { + this.pathCall = d3.line().x(d => xt(d.x)).y(d => yt(d.y)); + } + setConfig(sweepExtentSt) { + // Domain Calculate + let { + xExtent, + yExtent + } = sweepExtentSt || { + xExtent: false, + yExtent: false + }; + if (!xExtent || !yExtent) { + let allData = [...this.data]; + if (this.otherLineData) { + this.otherLineData.forEach(lineData => { + allData = [...allData, ...lineData.data]; + }); + } + const xes = d3.extent(allData, d => d.x).sort((a, b) => a - b); + xExtent = { + xL: xes[0], + xU: xes[1] + }; + const btm = d3.min(allData, d => d.y); + const top = d3.max(allData, d => d.y); + const height = top - btm; + yExtent = { + yL: btm - this.factor * height, + yU: top + this.factor * height + }; + } + this.scales.x.domain([xExtent.xL, xExtent.xU]); + this.scales.y.domain([yExtent.yL, yExtent.yU]); + + // rescale for zoom + const { + xt, + yt + } = (0, _compass.TfRescale)(this); + + // Axis Call + this.axisCall.x.scale(xt); + this.axisCall.y.scale(yt); + this.currentExtent = { + xExtent, + yExtent + }; + } + drawLine() { + const { + xt, + yt + } = (0, _compass.TfRescale)(this); + this.updatePathCall(xt, yt); + this.path.attr('d', this.pathCall(this.data)); + this.path.style('stroke', this.pathColor); + if (this.layout === _list_layout.LIST_LAYOUT.AIF) { + this.path.attr('marker-mid', 'url(#arrow-left)'); + } + } + drawThres() { + if (this.tTrEndPts.length > 0) { + this.thresLineUp.attr('d', this.pathCall(this.tTrEndPts)); + this.thresLineUp.attr('visibility', 'visible'); + const [left, right] = this.tTrEndPts; + const dwMirrorEndPts = [Object.assign({}, left, { + y: -left.y + }), Object.assign({}, right, { + y: -right.y + })]; + this.thresLineDw.attr('d', this.pathCall(dwMirrorEndPts)); + this.thresLineDw.attr('visibility', 'visible'); + } else { + this.thresLineUp.attr('visibility', 'hidden'); + this.thresLineDw.attr('visibility', 'hidden'); + } + } + drawOtherLines(layout) { + d3.selectAll('.line-clip-compare').remove(); + if (!this.otherLineData) return null; + this.otherLineData.forEach((entry, idx) => { + const { + data, + color + } = entry; + const pathColor = color ? color : _format.default.mutiEntitiesColors(idx); + const path = (0, _mount.MountComparePath)(this, pathColor, idx, 0.4); + path.attr('d', this.pathCall(data)); + if (this.layout === _list_layout.LIST_LAYOUT.AIF && this.isShowAllCurves === true) { + path.attr('marker-mid', 'url(#arrow-left)'); + } + }); + return null; + } + drawGrid() { + const { + sameXY + } = this.shouldUpdate; + if (sameXY) return; + this.grid.x.call(this.axisCall.x.tickSize(-this.h, 0, 0)).selectAll('line').attr('stroke', '#ddd').attr('stroke-opacity', 0.6).attr('fill', 'none'); + this.grid.y.call(this.axisCall.y.tickSize(-this.w, 0, 0)).selectAll('line').attr('stroke', '#ddd').attr('stroke-opacity', 0.6).attr('fill', 'none'); + } + onClickTarget(event, data) { + event.stopPropagation(); + event.preventDefault(); + const onPeak = true; + if (this.layout === _list_layout.LIST_LAYOUT.CYCLIC_VOLTAMMETRY) { + const { + spectraList + } = this.cyclicvoltaSt; + const spectra = spectraList[this.jcampIdx]; + const voltammetryPeakIdx = spectra.selectedIdx; + this.clickUiTargetAct(data, onPeak, voltammetryPeakIdx, this.jcampIdx); + } else { + this.clickUiTargetAct(data, onPeak, false, this.jcampIdx); + } + } + onClickPecker(event, data) { + event.stopPropagation(); + event.preventDefault(); + const onPecker = true; + const { + spectraList + } = this.cyclicvoltaSt; + const spectra = spectraList[this.jcampIdx]; + const voltammetryPeakIdx = spectra.selectedIdx; + this.clickUiTargetAct(data, false, voltammetryPeakIdx, this.jcampIdx, onPecker); + } + mergedPeaks(editPeakSt) { + if (!editPeakSt) return this.dataPks; + const { + spectraList + } = this.cyclicvoltaSt; + const spectra = spectraList[this.jcampIdx]; + if (spectra) { + this.dataPks = []; + this.dataPks = (0, _converter.PksEdit)(this.dataPks, editPeakSt, spectra.list); + } else { + const newEditPeaks = Object.assign({}, editPeakSt, { + selectedIdx: this.jcampIdx + }); + this.dataPks = (0, _converter.PksEdit)(this.dataPks, newEditPeaks, []); + } + return this.dataPks; + } + setDataPecker() { + const { + spectraList + } = this.cyclicvoltaSt; + const spectra = spectraList[this.jcampIdx]; + if (spectra) { + this.dataPeckers = (0, _converter.PeckersEdit)(spectra.list); + } + return this.dataPeckers; + } + drawAUC(stack) { + const { + xt, + yt + } = (0, _compass.TfRescale)(this); + const auc = this.tags.aucPath.selectAll('path').data(stack); + auc.exit().attr('class', 'exit').remove(); + const integCurve = border => { + const { + xL, + xU + } = border; + const ps = this.data.filter(d => d.x > xL && d.x < xU); + if (!ps[0]) return null; + const point1 = ps[0]; + const point2 = ps[ps.length - 1]; + const slope = (0, _calc.calcSlope)(point1.x, point1.y, point2.x, point2.y); + let lastDY = point1.y; + return d3.area().x(d => xt(d.x)).y0((d, index) => { + if (index > 0) { + const lastD = ps[index - 1]; + const y = slope * (d.x - lastD.x) + lastDY; + lastDY = y; + return yt(y); + } + return yt(0); + }).y1(d => yt(d.y))(ps); + }; + auc.enter().append('path').attr('class', 'auc').attr('fill', 'red').attr('stroke', 'none').attr('fill-opacity', 0.2).attr('stroke-width', 2).merge(auc).attr('d', d => integCurve(d)).attr('id', d => `auc${(0, _focus.itgIdTag)(d)}`).on('mouseover', (event, d) => { + d3.select(`#auc${(0, _focus.itgIdTag)(d)}`).attr('stroke', 'blue'); + d3.select(`#auc${(0, _focus.itgIdTag)(d)}`).attr('stroke', 'blue'); + d3.select(`#auc${(0, _focus.itgIdTag)(d)}`).style('fill', 'blue'); + }).on('mouseout', (event, d) => { + d3.select(`#auc${(0, _focus.itgIdTag)(d)}`).attr('stroke', 'none'); + d3.select(`#auc${(0, _focus.itgIdTag)(d)}`).style('fill', 'red'); + d3.select(`#auc${(0, _focus.itgIdTag)(d)}`).style('fill-opacity', 0.2); + }).on('click', (event, d) => this.onClickTarget(event, d)); + } + drawPeaks(editPeakSt) { + const { + sameXY, + sameEpSt, + sameDtPk, + sameSfPk + } = this.shouldUpdate; + if (!_format.default.isCyclicVoltaLayout(this.layout) && sameXY && sameEpSt && sameDtPk && sameSfPk) return; + + // rescale for zoom + const { + xt, + yt + } = (0, _compass.TfRescale)(this); + const dPks = this.mergedPeaks(editPeakSt); + const { + spectraList + } = this.cyclicvoltaSt; + const spectra = spectraList[this.jcampIdx]; + let indexOfCVRefPeaks = []; + if (spectra) { + const { + shift, + hasRefPeak + } = spectra; + const { + ref + } = shift; + if (ref && hasRefPeak) { + const { + min, + max + } = ref; + indexOfCVRefPeaks = dPks.map((p, index) => { + return p === min || p === max ? -1 : index; + }); + } + } + const mpp = this.tags.pPath.selectAll('path').data(dPks); + mpp.exit().attr('class', 'exit').remove(); + const linePath = [{ + x: -0.5, + y: 10 + }, { + x: -0.5, + y: -20 + }, { + x: 0.5, + y: -20 + }, { + x: 0.5, + y: 10 + }]; + const lineSymbol = d3.line().x(d => d.x).y(d => d.y)(linePath); + const lineRefPath = [{ + x: -0.5, + y: 10 + }, { + x: -4, + y: -20 + }, { + x: 4, + y: -20 + }, { + x: 0.5, + y: 10 + }]; + const lineSymbolRef = d3.line().x(d => d.x).y(d => d.y)(lineRefPath); + mpp.enter().append('path').attr('d', (_, index) => { + return indexOfCVRefPeaks[index] === -1 ? lineSymbolRef : lineSymbol; + }).attr('class', 'enter-peak').attr('fill', (_, index) => { + return indexOfCVRefPeaks[index] === -1 ? 'blue' : '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) => { + d3.select(`#mpp${Math.round(1000 * d.x)}`).attr('stroke-opacity', '1.0'); + d3.select(`#bpt${Math.round(1000 * d.x)}`).style('fill', 'blue'); + const tipParams = { + d, + layout: this.layout + }; + this.tip.show(tipParams, event.target); + }).on('mouseout', (event, d) => { + d3.select(`#mpp${Math.round(1000 * d.x)}`).attr('stroke-opacity', '0.0'); + d3.select(`#bpt${Math.round(1000 * d.x)}`).style('fill', 'red'); + const tipParams = { + d, + layout: this.layout + }; + this.tip.hide(tipParams, event.target); + }).on('click', (event, d) => this.onClickTarget(event, d)); + const ignoreRef = _format.default.isHplcUvVisLayout(this.layout); + if (ignoreRef) { + const bpTxt = this.tags.bpTxt.selectAll('text').data(dPks); + bpTxt.exit().attr('class', 'exit').remove(); + 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)); + } + mpp.attr('fill', (_, index) => { + return indexOfCVRefPeaks[index] === -1 ? 'blue' : 'red'; + }); + mpp.attr('d', (_, index) => { + return indexOfCVRefPeaks[index] === -1 ? lineSymbolRef : lineSymbol; + }); + } + drawPeckers() { + const { + sameXY, + sameEpSt, + sameDtPk, + sameSfPk + } = this.shouldUpdate; + if (!_format.default.isCyclicVoltaLayout(this.layout) && sameXY && sameEpSt && sameDtPk && sameSfPk) return; + + // rescale for zoom + const { + xt, + yt + } = (0, _compass.TfRescale)(this); + const dPks = this.setDataPecker(); + const mpp = this.tags.peckerPath.selectAll('path').data(dPks); + mpp.exit().attr('class', 'exit').remove(); + const linePath = [{ + x: -0.5, + y: 10 + }, { + x: -0.5, + y: -20 + }, { + x: 0.5, + y: -20 + }, { + x: 0.5, + y: 10 + }]; + const lineSymbol = d3.line().x(d => d.x).y(d => d.y)(linePath); + mpp.enter().append('path').attr('d', lineSymbol).attr('class', 'enter-peak').attr('fill', '#228B22').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) => { + d3.select(`#mpp${Math.round(1000 * d.x)}`).attr('stroke-opacity', '1.0'); + d3.select(`#bpt${Math.round(1000 * d.x)}`).style('fill', 'blue'); + const tipParams = { + d, + layout: this.layout + }; + this.tip.show(tipParams, event.target); + }).on('mouseout', (event, d) => { + d3.select(`#mpp${Math.round(1000 * d.x)}`).attr('stroke-opacity', '0.0'); + d3.select(`#bpt${Math.round(1000 * d.x)}`).style('fill', '#228B22'); + const tipParams = { + d, + layout: this.layout + }; + this.tip.hide(tipParams, event.target); + }).on('click', (event, d) => this.onClickPecker(event, d)); + } + drawInteg(integationSt) { + const { + sameXY, + sameLySt, + sameItSt, + sameData + } = this.shouldUpdate; + if (sameXY && sameLySt && sameItSt && sameData) return; + const { + integrations + } = integationSt; + const selectedIntegration = integrations[this.jcampIdx]; + if (selectedIntegration === false || selectedIntegration === undefined) { + const itgs = []; + const igbp = this.tags.igbPath.selectAll('path').data(itgs); + igbp.exit().attr('class', 'exit').remove(); + const igcp = this.tags.igcPath.selectAll('path').data(itgs); + igcp.exit().attr('class', 'exit').remove(); + const igtp = this.tags.igtPath.selectAll('text').data(itgs); + igtp.exit().attr('class', 'exit').remove(); + return; + } + const { + stack, + refArea, + refFactor, + shift + } = selectedIntegration; + const isDisable = _cfg.default.btnCmdIntg(this.layout); + const ignoreRef = _format.default.isHplcUvVisLayout(this.layout); + const itgs = isDisable ? [] : stack; + const igbp = this.tags.igbPath.selectAll('path').data(itgs); + igbp.exit().attr('class', 'exit').remove(); + const igcp = this.tags.igcPath.selectAll('path').data(itgs); + igcp.exit().attr('class', 'exit').remove(); + const igtp = this.tags.igtPath.selectAll('text').data(itgs); + igtp.exit().attr('class', 'exit').remove(); + if (itgs.length === 0 || isDisable) { + // remove drawn area under curve + const auc = this.tags.aucPath.selectAll('path').data(stack); + auc.exit().attr('class', 'exit').remove(); + auc.merge(auc); + return; + } + if (ignoreRef) { + this.drawAUC(stack); + } else { + // rescale for zoom + const { + xt + } = (0, _compass.TfRescale)(this); + const dh = 50; + const integBar = data => d3.line()([[xt(data.xL - shift), dh], [xt(data.xL - shift), dh - 10], [xt(data.xL - shift), dh - 5], [xt(data.xU - shift), dh - 5], [xt(data.xU - shift), dh - 10], [xt(data.xU - shift), dh]]); + igbp.enter().append('path').attr('class', 'igbp').attr('fill', 'none').attr('stroke', '#228B22').attr('stroke-width', 2).merge(igbp).attr('id', d => `igbp${(0, _focus.itgIdTag)(d)}`).attr('d', d => integBar(d)).on('mouseover', (event, d) => { + d3.select(`#igbp${(0, _focus.itgIdTag)(d)}`).attr('stroke', 'blue'); + d3.select(`#igbc${(0, _focus.itgIdTag)(d)}`).attr('stroke', 'blue'); + d3.select(`#igtp${(0, _focus.itgIdTag)(d)}`).style('fill', 'blue'); + }).on('mouseout', (event, d) => { + d3.select(`#igbp${(0, _focus.itgIdTag)(d)}`).attr('stroke', '#228B22'); + d3.select(`#igbc${(0, _focus.itgIdTag)(d)}`).attr('stroke', '#228B22'); + d3.select(`#igtp${(0, _focus.itgIdTag)(d)}`).style('fill', '#228B22'); + }).on('click', (event, d) => this.onClickTarget(event, d)); + const integCurve = border => { + const { + xL, + xU + } = border; + const [nXL, nXU] = [xL - shift, xU - shift]; + const ps = this.data.filter(d => d.x > nXL && d.x < nXU); + const kMax = this.data[this.data.length - 1].k; + if (!ps[0]) return null; + const kRef = ps[0].k; + if (!this.reverseXAxis(this.layout)) { + return d3.line().x(d => xt(d.x)).y(d => 100 - (kRef - d.k) * 400 / kMax)(ps); + } + return d3.line().x(d => xt(d.x)).y(d => 300 - (d.k - kRef) * 400 / kMax)(ps); + }; + igcp.enter().append('path').attr('class', 'igcp').attr('fill', 'none').attr('stroke', '#228B22').attr('stroke-width', 2).merge(igcp).attr('id', d => `igbc${(0, _focus.itgIdTag)(d)}`).attr('d', d => integCurve(d)).on('mouseover', (event, d) => { + d3.select(`#igbp${(0, _focus.itgIdTag)(d)}`).attr('stroke', 'blue'); + d3.select(`#igbc${(0, _focus.itgIdTag)(d)}`).attr('stroke', 'blue'); + d3.select(`#igtp${(0, _focus.itgIdTag)(d)}`).style('fill', 'blue'); + }).on('mouseout', (event, d) => { + d3.select(`#igbp${(0, _focus.itgIdTag)(d)}`).attr('stroke', '#228B22'); + d3.select(`#igbc${(0, _focus.itgIdTag)(d)}`).attr('stroke', '#228B22'); + d3.select(`#igtp${(0, _focus.itgIdTag)(d)}`).style('fill', '#228B22'); + }).on('click', (event, d) => this.onClickTarget(event, d)); + igtp.enter().append('text').attr('class', 'igtp').attr('font-family', 'Helvetica').style('font-size', '12px').attr('fill', '#228B22').style('text-anchor', 'middle').merge(igtp).attr('id', d => `igtp${(0, _focus.itgIdTag)(d)}`).text(d => (0, _integration.calcArea)(d, refArea, refFactor, ignoreRef)).attr('transform', d => `translate(${xt((d.xL + d.xU) / 2 - shift)}, ${dh - 12})`).on('mouseover', (event, d) => { + d3.select(`#igbp${(0, _focus.itgIdTag)(d)}`).attr('stroke', 'blue'); + d3.select(`#igbc${(0, _focus.itgIdTag)(d)}`).attr('stroke', 'blue'); + d3.select(`#igtp${(0, _focus.itgIdTag)(d)}`).style('fill', 'blue'); + }).on('mouseout', (event, d) => { + d3.select(`#igbp${(0, _focus.itgIdTag)(d)}`).attr('stroke', '#228B22'); + d3.select(`#igbc${(0, _focus.itgIdTag)(d)}`).attr('stroke', '#228B22'); + d3.select(`#igtp${(0, _focus.itgIdTag)(d)}`).style('fill', '#228B22'); + }).on('click', (event, d) => this.onClickTarget(event, d)); + } + } + drawMtply(mtplySt) { + const { + sameXY, + sameLySt, + sameMySt + } = this.shouldUpdate; + if (sameXY && sameLySt && sameMySt) return; + const { + multiplicities + } = mtplySt; + const selectedMulti = multiplicities[this.jcampIdx]; + if (selectedMulti === false || selectedMulti === undefined) { + const mpys = []; + const mpyb = this.tags.mpybPath.selectAll('path').data(mpys); + mpyb.exit().attr('class', 'exit').remove(); + const mpyt1 = this.tags.mpyt1Path.selectAll('text').data(mpys); + mpyt1.exit().attr('class', 'exit').remove(); + const mpyt2 = this.tags.mpyt2Path.selectAll('text').data(mpys); + mpyt2.exit().attr('class', 'exit').remove(); + let mPeaks = mpys.map(m => { + const { + peaks, + xExtent + } = m; + return peaks.map(p => Object.assign({}, p, { + xExtent + })); + }); + mPeaks = [].concat(...mPeaks); + const mpyp = this.tags.mpypPath.selectAll('path').data(mPeaks); + mpyp.exit().attr('class', 'exit').remove(); + return; + } + const { + stack, + smExtext, + shift + } = selectedMulti; + const mpys = stack; + const isDisable = _cfg.default.btnCmdMpy(this.layout); + if (mpys === 0 || isDisable) return; + // rescale for zoom + const { + xt + } = (0, _compass.TfRescale)(this); + const mpyb = this.tags.mpybPath.selectAll('path').data(mpys); + mpyb.exit().attr('class', 'exit').remove(); + const mpyt1 = this.tags.mpyt1Path.selectAll('text').data(mpys); + mpyt1.exit().attr('class', 'exit').remove(); + const mpyt2 = this.tags.mpyt2Path.selectAll('text').data(mpys); + mpyt2.exit().attr('class', 'exit').remove(); + let mPeaks = mpys.map(m => { + const { + peaks, + xExtent + } = m; + return peaks.map(p => Object.assign({}, p, { + xExtent + })); + }); + mPeaks = [].concat(...mPeaks); + const mpyp = this.tags.mpypPath.selectAll('path').data(mPeaks); + mpyp.exit().attr('class', 'exit').remove(); + const height = this.h; + const dh = Math.abs(0.06 * height); + const mpyBar = data => d3.line()([[xt(data.xExtent.xL - shift), height - dh], [xt(data.xExtent.xL - shift), height - dh - 10], [xt(data.xExtent.xL - shift), height - dh - 5], [xt(data.xExtent.xU - shift), height - dh - 5], [xt(data.xExtent.xU - shift), height - dh - 10], [xt(data.xExtent.xU - shift), height - dh]]); + const mpyColor = d => { + const { + xL, + xU + } = d.xExtent; + return smExtext.xL === xL && smExtext.xU === xU ? 'purple' : '#DA70D6'; + }; + mpyb.enter().append('path').attr('class', 'mpyb').attr('fill', 'none').attr('stroke-width', 2).merge(mpyb).attr('stroke', d => mpyColor(d)).attr('id', d => `mpyb${(0, _focus.mpyIdTag)(d)}`).attr('d', d => mpyBar(d)).on('mouseover', (event, d) => { + d3.selectAll(`#mpyb${(0, _focus.mpyIdTag)(d)}`).attr('stroke', 'blue'); + d3.selectAll(`#mpyt1${(0, _focus.mpyIdTag)(d)}`).style('fill', 'blue'); + d3.selectAll(`#mpyt2${(0, _focus.mpyIdTag)(d)}`).style('fill', 'blue'); + d3.selectAll(`#mpyp${(0, _focus.mpyIdTag)(d)}`).attr('stroke', 'blue'); + }).on('mouseout', (event, d) => { + const dColor = mpyColor(d); + d3.selectAll(`#mpyb${(0, _focus.mpyIdTag)(d)}`).attr('stroke', dColor); + d3.selectAll(`#mpyt1${(0, _focus.mpyIdTag)(d)}`).style('fill', dColor); + d3.selectAll(`#mpyt2${(0, _focus.mpyIdTag)(d)}`).style('fill', dColor); + d3.selectAll(`#mpyp${(0, _focus.mpyIdTag)(d)}`).attr('stroke', dColor); + }).on('click', (event, d) => this.onClickTarget(event, d)); + mpyt1.enter().append('text').attr('class', 'mpyt1').attr('font-family', 'Helvetica').style('font-size', '12px').style('text-anchor', 'middle').merge(mpyt1).attr('fill', d => mpyColor(d)).attr('id', d => `mpyt1${(0, _focus.mpyIdTag)(d)}`).text(d => `${(0, _multiplicity_calc.calcMpyCenter)(d.peaks, shift, d.mpyType).toFixed(3)}`).attr('transform', d => `translate(${xt((d.xExtent.xL + d.xExtent.xU) / 2 - shift)}, ${height - dh + 12})`).on('mouseover', (event, d) => { + d3.selectAll(`#mpyb${(0, _focus.mpyIdTag)(d)}`).attr('stroke', 'blue'); + d3.selectAll(`#mpyt1${(0, _focus.mpyIdTag)(d)}`).style('fill', 'blue'); + d3.selectAll(`#mpyt2${(0, _focus.mpyIdTag)(d)}`).style('fill', 'blue'); + d3.selectAll(`#mpyp${(0, _focus.mpyIdTag)(d)}`).attr('stroke', 'blue'); + }).on('mouseout', (event, d) => { + const dColor = mpyColor(d); + d3.selectAll(`#mpyb${(0, _focus.mpyIdTag)(d)}`).attr('stroke', dColor); + d3.selectAll(`#mpyt1${(0, _focus.mpyIdTag)(d)}`).style('fill', dColor); + d3.selectAll(`#mpyt2${(0, _focus.mpyIdTag)(d)}`).style('fill', dColor); + d3.selectAll(`#mpyp${(0, _focus.mpyIdTag)(d)}`).attr('stroke', dColor); + }).on('click', (event, d) => this.onClickTarget(event, d)); + mpyt2.enter().append('text').attr('class', 'mpyt2').attr('font-family', 'Helvetica').style('font-size', '12px').style('text-anchor', 'middle').merge(mpyt2).attr('fill', d => mpyColor(d)).attr('id', d => `mpyt2${(0, _focus.mpyIdTag)(d)}`).text(d => `(${d.mpyType})`).attr('transform', d => `translate(${xt((d.xExtent.xL + d.xExtent.xU) / 2 - shift)}, ${height - dh + 24})`).on('mouseover', (event, d) => { + d3.selectAll(`#mpyb${(0, _focus.mpyIdTag)(d)}`).attr('stroke', 'blue'); + d3.selectAll(`#mpyt1${(0, _focus.mpyIdTag)(d)}`).style('fill', 'blue'); + d3.selectAll(`#mpyt2${(0, _focus.mpyIdTag)(d)}`).style('fill', 'blue'); + d3.selectAll(`#mpyp${(0, _focus.mpyIdTag)(d)}`).attr('stroke', 'blue'); + }).on('mouseout', (event, d) => { + const dColor = mpyColor(d); + d3.selectAll(`#mpyb${(0, _focus.mpyIdTag)(d)}`).attr('stroke', dColor); + d3.selectAll(`#mpyt1${(0, _focus.mpyIdTag)(d)}`).style('fill', dColor); + d3.selectAll(`#mpyt2${(0, _focus.mpyIdTag)(d)}`).style('fill', dColor); + d3.selectAll(`#mpyp${(0, _focus.mpyIdTag)(d)}`).attr('stroke', dColor); + }).on('click', (event, d) => this.onClickTarget(event, d)); + const mpypH = height - dh; + const mpypPath = pk => [{ + x: xt(pk.x - shift) - 0.5, + y: mpypH - 5 + }, { + x: xt(pk.x - shift) - 0.5, + y: mpypH - 20 + }, { + x: xt(pk.x - shift) + 0.5, + y: mpypH - 20 + }, { + x: xt(pk.x - shift) + 0.5, + y: mpypH - 5 + }]; + // const faktor = layoutSt === LIST_LAYOUT.IR ? -1 : 1; + const lineSymbol = d3.line().x(d => d.x).y(d => d.y); + mpyp.enter().append('path').attr('class', 'mpyp').attr('fill', 'none').merge(mpyp).attr('stroke', d => mpyColor(d)).attr('d', d => lineSymbol(mpypPath(d))).attr('id', d => `mpyp${(0, _focus.mpyIdTag)(d)}`).on('mouseover', (event, d) => { + d3.selectAll(`#mpyb${(0, _focus.mpyIdTag)(d)}`).attr('stroke', 'blue'); + d3.selectAll(`#mpyt1${(0, _focus.mpyIdTag)(d)}`).style('fill', 'blue'); + d3.selectAll(`#mpyt2${(0, _focus.mpyIdTag)(d)}`).style('fill', 'blue'); + d3.selectAll(`#mpyp${(0, _focus.mpyIdTag)(d)}`).attr('stroke', 'blue'); + }).on('mouseout', (event, d) => { + const dColor = mpyColor(d); + d3.selectAll(`#mpyb${(0, _focus.mpyIdTag)(d)}`).attr('stroke', dColor); + d3.selectAll(`#mpyt1${(0, _focus.mpyIdTag)(d)}`).style('fill', dColor); + d3.selectAll(`#mpyt2${(0, _focus.mpyIdTag)(d)}`).style('fill', dColor); + d3.selectAll(`#mpyp${(0, _focus.mpyIdTag)(d)}`).attr('stroke', dColor); + }).on('click', (event, d) => this.onClickTarget(event, d)); + } + drawRef() { + // rescale for zoom + const { + xt, + yt + } = (0, _compass.TfRescale)(this); + const ccp = this.ref.selectAll('path').data(this.tSfPeaks); + ccp.exit().attr('class', 'exit').remove(); + const linePath = [{ + x: -0.5, + y: 10 + }, { + x: -4, + y: -20 + }, { + x: 4, + y: -20 + }, { + x: 0.5, + y: 10 + }]; + const faktor = _format.default.isIrLayout(this.layout) ? -1 : 1; + const lineSymbol = d3.line().x(d => d.x).y(d => faktor * d.y)(linePath); + ccp.enter().append('path').attr('d', lineSymbol).attr('class', 'enter-ref').attr('fill', 'green').attr('fill-opacity', 0.8).merge(ccp).attr('transform', d => `translate(${xt(d.x)}, ${yt(d.y)})`); + } + reverseXAxis(layoutSt) { + return [_list_layout.LIST_LAYOUT.UVVIS, _list_layout.LIST_LAYOUT.HPLC_UVVIS, _list_layout.LIST_LAYOUT.TGA, _list_layout.LIST_LAYOUT.DSC, _list_layout.LIST_LAYOUT.XRD, _list_layout.LIST_LAYOUT.CYCLIC_VOLTAMMETRY, _list_layout.LIST_LAYOUT.CDS, _list_layout.LIST_LAYOUT.SEC, _list_layout.LIST_LAYOUT.GC, _list_layout.LIST_LAYOUT.AIF].indexOf(layoutSt) < 0; + } + create(_ref) { + let { + curveSt, + filterSeed, + filterPeak, + tTrEndPts, + tSfPeaks, + editPeakSt, + layoutSt, + sweepExtentSt, + isUiNoBrushSt, + cyclicvoltaSt, + integationSt, + mtplySt + } = _ref; + this.svg = d3.select(this.rootKlass).select('.d3Svg'); + (0, _mount.MountMainFrame)(this, 'focus'); + (0, _mount.MountClip)(this); + const { + curveIdx, + isShowAllCurve + } = curveSt; + const jcampIdx = curveIdx; + this.isShowAllCurves = isShowAllCurve; + this.root = d3.select(this.rootKlass).selectAll('.focus-main'); + this.scales = (0, _init.InitScale)(this, this.reverseXAxis(layoutSt)); + this.setTip(); + this.setDataParams(filterSeed, filterPeak, tTrEndPts, tSfPeaks, layoutSt, cyclicvoltaSt, jcampIdx); + (0, _compass.MountCompass)(this); + this.axis = (0, _mount.MountAxis)(this); + this.path = (0, _mount.MountPath)(this, this.pathColor); + [this.thresLineUp, this.thresLineDw] = (0, _mount.MountThresLine)(this, 'green'); + this.grid = (0, _mount.MountGrid)(this); + this.tags = (0, _mount.MountTags)(this); + this.ref = (0, _mount.MountRef)(this); + (0, _mount.MountAxisLabelX)(this); + (0, _mount.MountAxisLabelY)(this); + if (this.data && this.data.length > 0) { + this.setConfig(sweepExtentSt); + this.drawLine(); + this.drawThres(); + this.drawGrid(); + this.drawOtherLines(layoutSt); + this.drawPeaks(editPeakSt); + this.drawRef(); + this.drawPeckers(); + this.drawInteg(integationSt); + this.drawMtply(mtplySt); + } + (0, _brush.default)(this, false, isUiNoBrushSt); + this.resetShouldUpdate(editPeakSt); + } + update(_ref2) { + let { + entities, + curveSt, + filterSeed, + filterPeak, + tTrEndPts, + tSfPeaks, + editPeakSt, + layoutSt, + sweepExtentSt, + isUiNoBrushSt, + cyclicvoltaSt, + integationSt, + mtplySt + } = _ref2; + this.root = d3.select(this.rootKlass).selectAll('.focus-main'); + this.scales = (0, _init.InitScale)(this, this.reverseXAxis(layoutSt)); + const { + curveIdx, + isShowAllCurve + } = curveSt; + const jcampIdx = curveIdx; + this.isShowAllCurves = isShowAllCurve; + this.entities = entities; + this.setDataParams(filterSeed, filterPeak, tTrEndPts, tSfPeaks, layoutSt, cyclicvoltaSt, jcampIdx); + if (this.data && this.data.length > 0) { + this.setConfig(sweepExtentSt); + this.getShouldUpdate(editPeakSt); + this.drawLine(); + this.drawThres(); + this.drawGrid(); + this.drawOtherLines(layoutSt); + this.drawPeaks(editPeakSt); + this.drawRef(); + this.drawPeckers(); + this.drawInteg(integationSt); + this.drawMtply(mtplySt); + } + (0, _brush.default)(this, false, isUiNoBrushSt); + this.resetShouldUpdate(editPeakSt); + } +} +var _default = exports.default = MultiFocus; \ No newline at end of file diff --git a/dist/components/d3_rect/index.js b/dist/components/d3_rect/index.js new file mode 100644 index 00000000..8c537de3 --- /dev/null +++ b/dist/components/d3_rect/index.js @@ -0,0 +1,152 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; +var _react = _interopRequireDefault(require("react")); +var _reactRedux = require("react-redux"); +var _redux = require("redux"); +var _propTypes = _interopRequireDefault(require("prop-types")); +var _chem = require("../../helpers/chem"); +var _manager = require("../../actions/manager"); +var _ui = require("../../actions/ui"); +var _rect_focus = _interopRequireDefault(require("./rect_focus")); +var _draw = require("../common/draw"); +var _list_ui = require("../../constants/list_ui"); +var _jsxRuntime = require("react/jsx-runtime"); +/* eslint-disable no-mixed-operators */ + +const W = Math.round(window.innerWidth * 0.90 * 9 / 12); // ROI +const H = Math.round(window.innerHeight * 0.90 * 0.85); // ROI + +class ViewerRect extends _react.default.Component { + constructor(props) { + super(props); + const { + clickUiTargetAct, + selectUiSweepAct, + scrollUiWheelAct + } = props; + this.rootKlass = '.d3Rect'; + this.focus = new _rect_focus.default({ + W, + H, + clickUiTargetAct, + selectUiSweepAct, + scrollUiWheelAct + }); + this.normChange = this.normChange.bind(this); + } + componentDidMount() { + const { + seed, + peak, + cLabel, + xLabel, + yLabel, + feature, + tTrEndPts, + tSfPeaks, + isHidden, + sweepExtentSt, + isUiAddIntgSt, + isUiNoBrushSt, + resetAllAct + } = this.props; + (0, _draw.drawDestroy)(this.rootKlass); + resetAllAct(feature); + const filterSeed = seed; + const filterPeak = peak; + (0, _draw.drawMain)(this.rootKlass, W, H); + this.focus.create({ + filterSeed, + filterPeak, + tTrEndPts, + tSfPeaks, + sweepExtentSt, + isUiAddIntgSt, + isUiNoBrushSt + }); + (0, _draw.drawLabel)(this.rootKlass, cLabel, xLabel, yLabel); + (0, _draw.drawDisplay)(this.rootKlass, isHidden); + } + componentDidUpdate(prevProps) { + const { + seed, + peak, + tTrEndPts, + tSfPeaks, + isHidden, + sweepExtentSt, + isUiAddIntgSt, + isUiNoBrushSt + } = this.props; + this.normChange(prevProps); + const filterSeed = seed; + const filterPeak = peak; + this.focus.update({ + filterSeed, + filterPeak, + tTrEndPts, + tSfPeaks, + sweepExtentSt, + isUiAddIntgSt, + isUiNoBrushSt + }); + (0, _draw.drawDisplay)(this.rootKlass, isHidden); + } + componentWillUnmount() { + (0, _draw.drawDestroy)(this.rootKlass); + } + normChange(prevProps) { + const { + feature, + resetAllAct + } = this.props; + const oldFeature = prevProps.feature; + if (oldFeature !== feature) { + resetAllAct(feature); + } + } + render() { + return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", { + className: "d3Rect" + }); + } +} +const mapStateToProps = (state, props) => ({ + seed: (0, _chem.Topic2Seed)(state, props), + peak: (0, _chem.Feature2Peak)(state, props), + tTrEndPts: (0, _chem.ToThresEndPts)(state, props), + tSfPeaks: (0, _chem.ToShiftPeaks)(state, props), + sweepExtentSt: state.ui.sweepExtent, + isUiAddIntgSt: state.ui.sweepType === _list_ui.LIST_UI_SWEEP_TYPE.INTEGRATION_ADD, + isUiNoBrushSt: _list_ui.LIST_NON_BRUSH_TYPES.indexOf(state.ui.sweepType) < 0 +}); +const mapDispatchToProps = dispatch => (0, _redux.bindActionCreators)({ + resetAllAct: _manager.resetAll, + clickUiTargetAct: _ui.clickUiTarget, + selectUiSweepAct: _ui.selectUiSweep, + scrollUiWheelAct: _ui.scrollUiWheel +}, dispatch); +ViewerRect.propTypes = { + seed: _propTypes.default.array.isRequired, + peak: _propTypes.default.array.isRequired, + cLabel: _propTypes.default.string.isRequired, + xLabel: _propTypes.default.string.isRequired, + yLabel: _propTypes.default.string.isRequired, + feature: _propTypes.default.object.isRequired, + tTrEndPts: _propTypes.default.array.isRequired, + tSfPeaks: _propTypes.default.array.isRequired, + sweepExtentSt: _propTypes.default.object.isRequired, + isUiAddIntgSt: _propTypes.default.bool.isRequired, + isUiNoBrushSt: _propTypes.default.bool.isRequired, + resetAllAct: _propTypes.default.func.isRequired, + clickUiTargetAct: _propTypes.default.func.isRequired, + selectUiSweepAct: _propTypes.default.func.isRequired, + scrollUiWheelAct: _propTypes.default.func.isRequired, + isHidden: _propTypes.default.bool.isRequired +}; +var _default = exports.default = (0, _reactRedux.connect)(mapStateToProps, mapDispatchToProps)(ViewerRect); \ No newline at end of file diff --git a/dist/components/d3_rect/rect_focus.js b/dist/components/d3_rect/rect_focus.js new file mode 100644 index 00000000..29d25af2 --- /dev/null +++ b/dist/components/d3_rect/rect_focus.js @@ -0,0 +1,225 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; +var _init = require("../../helpers/init"); +var _brush = _interopRequireDefault(require("../../helpers/brush")); +var _mount = require("../../helpers/mount"); +var _compass = require("../../helpers/compass"); +var _converter = require("../../helpers/converter"); +var _list_layout = require("../../constants/list_layout"); +const d3 = require('d3'); +class RectFocus { + constructor(props) { + const { + W, + H, + clickUiTargetAct, + selectUiSweepAct, + scrollUiWheelAct + } = props; + this.rootKlass = '.d3Rect'; + this.margin = { + t: 5, + b: 40, + l: 60, + r: 5 + }; + this.w = W - this.margin.l - this.margin.r; + this.h = H - this.margin.t - this.margin.b; + this.clickUiTargetAct = clickUiTargetAct; + this.selectUiSweepAct = selectUiSweepAct; + this.scrollUiWheelAct = scrollUiWheelAct; + this.brush = d3.brush(); + this.axis = null; + this.thresLine = null; + this.grid = null; + this.ref = null; + this.ccPattern = null; + this.data = []; + this.dataPks = []; + this.tTrEndPts = null; + this.tSfPeaks = null; + this.root = null; + this.svg = null; + this.bars = null; + this.scales = (0, _init.InitScale)(this, false); + this.axisCall = (0, _init.InitAxisCall)(5); + this.pathCall = null; + this.tip = null; + this.factor = 0.125; + this.currentExtent = null; + this.layout = _list_layout.LIST_LAYOUT.MS; + this.setTip = this.setTip.bind(this); + this.setDataParams = this.setDataParams.bind(this); + this.create = this.create.bind(this); + this.update = this.update.bind(this); + this.setConfig = this.setConfig.bind(this); + this.drawBar = this.drawBar.bind(this); + this.drawThres = this.drawThres.bind(this); + this.drawGrid = this.drawGrid.bind(this); + this.mergedPeaks = this.mergedPeaks.bind(this); + this.isFirefox = typeof InstallTrigger !== 'undefined'; + } + setTip() { + this.tip = (0, _init.InitTip)(); + this.root.call(this.tip); + } + setDataParams(data, peaks, tTrEndPts, tSfPeaks) { + this.data = [...data]; + this.dataPks = [...peaks]; + this.tTrEndPts = tTrEndPts; + this.tSfPeaks = tSfPeaks; + } + updatePathCall(xt, yt) { + this.pathCall = d3.line().x(d => xt(d.x)).y(d => yt(d.y)); + } + setConfig(sweepExtentSt) { + // Domain Calculate + let { + xExtent, + yExtent + } = sweepExtentSt || { + xExtent: false, + yExtent: false + }; + if (!xExtent || !yExtent) { + const xes = d3.extent(this.data, d => d.x).sort((a, b) => a - b); + xExtent = { + xL: xes[0] - 10, + xU: xes[1] + 10 + }; + const btm = 0; // MS baseline is always 0. + const top = d3.max(this.data, d => d.y); + const height = top - btm; + yExtent = { + yL: btm - this.factor * height, + yU: top + this.factor * height + }; + } + this.scales.x.domain([xExtent.xL, xExtent.xU]); + this.scales.y.domain([yExtent.yL, yExtent.yU]); + + // rescale for zoom + const { + xt, + yt + } = (0, _compass.TfRescale)(this); + + // Axis Call + this.axisCall.x.scale(xt); + this.axisCall.y.scale(yt); + this.currentExtent = { + xExtent, + yExtent + }; + } + posHeight(gnd, val) { + const h = gnd - val; + return h >= 0 ? h : 0; + } + barColor(y, yRef) { + return y >= yRef ? 'steelblue' : '#aaa'; + } + drawBar() { + const { + xt, + yt + } = (0, _compass.TfRescale)(this); + this.updatePathCall(xt, yt); + const yRef = this.tTrEndPts[0].y; + const bars = this.bars.selectAll('rect').data(this.data); + bars.exit().attr('class', 'exit').remove(); + const gnd = yt(0); + bars.enter().append('rect').attr('class', 'enter-bar').attr('width', 1.5).merge(bars).attr('fill', d => this.barColor(d.y, yRef)).attr('height', d => this.posHeight(gnd, yt(d.y))).attr('id', d => `mpp${Math.round(1000 * d.x)}`).attr('transform', d => `translate(${xt(d.x)}, ${yt(d.y)})`).on('mouseover', (event, d) => { + d3.select(`#mpp${Math.round(1000 * d.x)}`).attr('stroke-opacity', '1.0'); + d3.select(`#bpt${Math.round(1000 * d.x)}`).style('fill', 'blue'); + const tipParams = { + d, + layout: this.layout + }; + this.tip.show(tipParams, event.target); + }).on('mouseout', (event, d) => { + d3.select(`#mpp${Math.round(1000 * d.x)}`).attr('stroke-opacity', '1.0'); + d3.select(`#bpt${Math.round(1000 * d.x)}`).style('fill', 'red'); + const tipParams = { + d, + layout: this.layout + }; + this.tip.hide(tipParams, event.target); + }); + } + drawThres() { + if (this.tTrEndPts.length > 0) { + this.thresLine.attr('d', this.pathCall(this.tTrEndPts)); + this.thresLine.attr('visibility', 'visible'); + } else { + this.thresLine.attr('visibility', 'hidden'); + } + } + drawGrid() { + this.grid.x.call(this.axisCall.x.tickSize(-this.h, 0, 0)).selectAll('line').attr('stroke', '#ddd').attr('stroke-opacity', 0.6).attr('fill', 'none'); + this.grid.y.call(this.axisCall.y.tickSize(-this.w, 0, 0)).selectAll('line').attr('stroke', '#ddd').attr('stroke-opacity', 0.6).attr('fill', 'none'); + } + mergedPeaks(editPeakSt) { + if (!editPeakSt) return this.dataPks; + this.dataPks = (0, _converter.PksEdit)(this.dataPks, editPeakSt); + return this.dataPks; + } + create(_ref) { + let { + filterSeed, + filterPeak, + tTrEndPts, + tSfPeaks, + sweepExtentSt, + isUiAddIntgSt, + isUiNoBrushSt + } = _ref; + this.svg = d3.select('.d3Svg'); + (0, _mount.MountMainFrame)(this, 'focus'); + (0, _mount.MountClip)(this); + this.root = d3.select(this.rootKlass).selectAll('.focus-main'); + this.setTip(); + this.setDataParams(filterSeed, filterPeak, tTrEndPts, tSfPeaks); + (0, _compass.MountCompass)(this); + this.axis = (0, _mount.MountAxis)(this); + [this.thresLine] = (0, _mount.MountThresLine)(this, 'green'); + this.grid = (0, _mount.MountGrid)(this); + this.ref = (0, _mount.MountRef)(this); + this.bars = (0, _mount.MountBars)(this); + (0, _mount.MountAxisLabelX)(this); + (0, _mount.MountAxisLabelY)(this); + if (this.data && this.data.length > 0) { + this.setConfig(sweepExtentSt); + this.drawBar(); + this.drawThres(); + this.drawGrid(); + } + (0, _brush.default)(this, isUiAddIntgSt, isUiNoBrushSt); + } + update(_ref2) { + let { + filterSeed, + filterPeak, + tTrEndPts, + tSfPeaks, + sweepExtentSt, + isUiAddIntgSt, + isUiNoBrushSt + } = _ref2; + this.root = d3.select(this.rootKlass).selectAll('.focus-main'); + this.setDataParams(filterSeed, filterPeak, tTrEndPts, tSfPeaks); + if (this.data && this.data.length > 0) { + this.setConfig(sweepExtentSt); + this.drawBar(); + this.drawThres(); + this.drawGrid(); + } + (0, _brush.default)(this, isUiAddIntgSt, isUiNoBrushSt); + } +} +var _default = exports.default = RectFocus; \ No newline at end of file diff --git a/dist/components/forecast/comps.js b/dist/components/forecast/comps.js new file mode 100644 index 00000000..e2d3edcc --- /dev/null +++ b/dist/components/forecast/comps.js @@ -0,0 +1,241 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.sectionSvg = exports.sectionInput = exports.notToRenderAnalysis = exports.TxtLabel = exports.StatusIcon = exports.ConfidenceLabel = void 0; +var _react = _interopRequireDefault(require("react")); +var _classnames = _interopRequireDefault(require("classnames")); +var _reactSvgFileZoomPan = _interopRequireDefault(require("@complat/react-svg-file-zoom-pan")); +var _CheckCircleOutline = _interopRequireDefault(require("@mui/icons-material/CheckCircleOutline")); +var _ErrorOutline = _interopRequireDefault(require("@mui/icons-material/ErrorOutline")); +var _HighlightOff = _interopRequireDefault(require("@mui/icons-material/HighlightOff")); +var _HelpOutline = _interopRequireDefault(require("@mui/icons-material/HelpOutline")); +var _Help = _interopRequireDefault(require("@mui/icons-material/Help")); +var _material = require("@mui/material"); +var _CloudOff = _interopRequireDefault(require("@mui/icons-material/CloudOff")); +var _section_loading = _interopRequireDefault(require("./section_loading")); +var _jsxRuntime = require("react/jsx-runtime"); +/* eslint-disable react/function-component-definition, react/destructuring-assignment, +max-len */ + +const titleStyle = { + backgroundColor: '#f5f5f5', + border: '2px solid #e3e3e3', + borderRadius: '10px', + lineHeight: '200px', + marginBottom: 10, + marginTop: 10, + marginLeft: 40, + textAlign: 'center', + width: '70%' +}; +const txtStyle = { + lineHeight: '20px' +}; +const TxtLabel = exports.TxtLabel = function TxtLabel(classes, label) { + let extClsName = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'txt-label'; + return /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: (0, _classnames.default)(classes.txtLabel, extClsName), + children: label + }); +}; +const StatusIcon = status => { + switch (status) { + case 'accept': + return /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Tooltip, { + title: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: "txt-sv-tp", + children: "Accept" + }), + placement: "left", + children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_CheckCircleOutline.default, { + style: { + color: '#4caf50' + } + }) + }); + case 'warning': + return /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Tooltip, { + title: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: "txt-sv-tp", + children: "Warning" + }), + placement: "left", + children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_ErrorOutline.default, { + style: { + color: '#ffc107' + } + }) + }); + case 'reject': + return /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Tooltip, { + title: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: "txt-sv-tp", + children: "Reject" + }), + placement: "left", + children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_HighlightOff.default, { + style: { + color: '#e91e63' + } + }) + }); + case 'missing': + return /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Tooltip, { + title: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: "txt-sv-tp", + children: "Missing" + }), + placement: "left", + children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_HelpOutline.default, { + style: { + color: '#5d4037' + } + }) + }); + case 'unknown': + return /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Tooltip, { + title: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: "txt-sv-tp", + children: "Not Support" + }), + placement: "left", + children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Help.default, { + style: { + color: '#5d4037' + } + }) + }); + default: + return null; + } +}; +exports.StatusIcon = StatusIcon; +const ConfidenceLabel = exports.ConfidenceLabel = function ConfidenceLabel(classes, confidence) { + let extClsName = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'txt-label'; + if (!confidence) return /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + children: " - - " + }); + const confidenceDp = parseFloat(Math.round(confidence * 100) / 100).toFixed(2); + return /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: (0, _classnames.default)(classes.txtLabel, extClsName), + children: `${confidenceDp} %` + }); +}; +const sectionInput = (classes, molecule, inputFuncCb) => { + if (!inputFuncCb) return null; + return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", { + className: (0, _classnames.default)(classes.inputRoot), + children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Grid, { + container: true, + children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Grid, { + item: true, + xs: 6, + children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.TextField, { + fullWidth: true, + label: TxtLabel(classes, 'Molfile', 'txt-mol-label'), + margin: "normal", + multiline: true, + onChange: inputFuncCb, + rows: "2", + variant: "outlined", + value: molecule + }) + }) + }) + }); +}; +exports.sectionInput = sectionInput; +const SectionRunning = () => /*#__PURE__*/(0, _jsxRuntime.jsx)("div", { + style: titleStyle, + children: /*#__PURE__*/(0, _jsxRuntime.jsxs)("h2", { + style: txtStyle, + children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_material.CircularProgress, { + style: { + color: 'blue', + fontSize: 50 + } + }), /*#__PURE__*/(0, _jsxRuntime.jsx)("br", {}), /*#__PURE__*/(0, _jsxRuntime.jsx)("br", {}), /*#__PURE__*/(0, _jsxRuntime.jsx)("p", { + children: "The server is making predictions..." + })] + }) +}); +const SectionMissMatch = () => /*#__PURE__*/(0, _jsxRuntime.jsx)("div", { + style: titleStyle, + children: /*#__PURE__*/(0, _jsxRuntime.jsxs)("h2", { + style: txtStyle, + children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_ErrorOutline.default, { + style: { + color: 'red', + fontSize: 50 + } + }), /*#__PURE__*/(0, _jsxRuntime.jsx)("p", { + className: "txt-predict-fail", + children: "Peak & Element count mismatch!" + }), /*#__PURE__*/(0, _jsxRuntime.jsxs)("p", { + className: "txt-predict-fail", + children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("sup", { + children: "1" + }), "H multiplicity count should not be more than the proton group count. Multiplicity must be assigned manulally before predictions."] + }), /*#__PURE__*/(0, _jsxRuntime.jsxs)("p", { + className: "txt-predict-fail", + children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("sup", { + children: "13" + }), "C peak count should not be more than the carbon count, and solvent peaks should be excluded."] + })] + }) +}); +const SectionNoService = () => /*#__PURE__*/(0, _jsxRuntime.jsx)("div", { + style: titleStyle, + children: /*#__PURE__*/(0, _jsxRuntime.jsxs)("h2", { + style: txtStyle, + children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_CloudOff.default, { + style: { + color: 'red', + fontSize: 50 + } + }), /*#__PURE__*/(0, _jsxRuntime.jsx)("p", { + children: "Service is not available." + }), /*#__PURE__*/(0, _jsxRuntime.jsx)("p", { + children: "Please try it again later." + })] + }) +}); +const SectionUnknown = () => /*#__PURE__*/(0, _jsxRuntime.jsx)("div", { + style: titleStyle, + children: /*#__PURE__*/(0, _jsxRuntime.jsxs)("h2", { + style: txtStyle, + children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_HelpOutline.default, { + style: { + color: 'purple', + fontSize: 50 + } + }), /*#__PURE__*/(0, _jsxRuntime.jsx)("p", { + children: "Unknown state." + })] + }) +}); +const notToRenderAnalysis = pds => { + if (pds.running) return /*#__PURE__*/(0, _jsxRuntime.jsx)(SectionRunning, {}); + if (!pds.outline || !pds.outline.code) return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {}); + if (pds.outline.code >= 500) return /*#__PURE__*/(0, _jsxRuntime.jsx)(SectionNoService, {}); + if (pds.outline.code === 400) return /*#__PURE__*/(0, _jsxRuntime.jsx)(SectionMissMatch, {}); + if (pds.outline.code >= 300) return /*#__PURE__*/(0, _jsxRuntime.jsx)(SectionUnknown, {}); + return false; +}; +exports.notToRenderAnalysis = notToRenderAnalysis; +const sectionSvg = (classes, predictions) => { + const renderMsg = notToRenderAnalysis(predictions); + if (renderMsg) return null; + if (!predictions.output) return null; + const targetSvg = predictions.output.result[0].svgs[0]; + if (!targetSvg) return /*#__PURE__*/(0, _jsxRuntime.jsx)(_section_loading.default, {}); + return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactSvgFileZoomPan.default, { + svg: targetSvg, + duration: 300, + resize: true + }); +}; +exports.sectionSvg = sectionSvg; \ No newline at end of file diff --git a/dist/components/forecast/ir_comps.js b/dist/components/forecast/ir_comps.js new file mode 100644 index 00000000..68aec036 --- /dev/null +++ b/dist/components/forecast/ir_comps.js @@ -0,0 +1,159 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.IrTableHeader = exports.IrTableBodyRow = void 0; +var _react = _interopRequireDefault(require("react")); +var _propTypes = _interopRequireDefault(require("prop-types")); +var _reactRedux = require("react-redux"); +var _redux = require("redux"); +var _classnames = _interopRequireDefault(require("classnames")); +var _material = require("@mui/material"); +var _CheckCircleOutline = _interopRequireDefault(require("@mui/icons-material/CheckCircleOutline")); +var _HighlightOff = _interopRequireDefault(require("@mui/icons-material/HighlightOff")); +var _comps = require("./comps"); +var _forecast = require("../../actions/forecast"); +var _jsxRuntime = require("react/jsx-runtime"); +/* eslint-disable react/function-component-definition, function-paren-newline, +prefer-object-spread */ + +// import SmaToSvg from '../common/chem'; +const baseSelectIrStatus = _ref => { + let { + sma, + status, + identity, + curveIdx, + setIrStatusAct + } = _ref; + const theStatus = ['accept', 'reject'].includes(status) ? status : ''; + return /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.FormControl, { + children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_material.Select, { + value: theStatus, + onChange: e => { + setIrStatusAct({ + predictions: { + sma, + identity, + value: e.target.value + }, + svgs: [], + curveIdx + }); + }, + children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_material.MenuItem, { + value: "accept", + children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_CheckCircleOutline.default, { + style: { + color: '#4caf50' + } + }) + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.MenuItem, { + value: "reject", + children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_HighlightOff.default, { + style: { + color: '#e91e63' + } + }) + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.MenuItem, { + value: "", + children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", {}) + })] + }) + }); +}; +const bssMapStateToProps = (state, props) => ( +// eslint-disable-line +{ + curveIdx: state.curve.curveIdx +}); +const bssMapDispatchToProps = dispatch => (0, _redux.bindActionCreators)({ + setIrStatusAct: _forecast.setIrStatus +}, dispatch); +baseSelectIrStatus.propTypes = { + sma: _propTypes.default.string.isRequired, + status: _propTypes.default.string, + identity: _propTypes.default.string.isRequired, + curveIdx: _propTypes.default.number.isRequired, + setIrStatusAct: _propTypes.default.func.isRequired +}; +baseSelectIrStatus.defaultProps = { + status: '' +}; +const SelectIrStatus = (0, _reactRedux.connect)(bssMapStateToProps, bssMapDispatchToProps)(baseSelectIrStatus); +const IrTableHeader = classes => /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.TableHead, { + children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_material.TableRow, { + children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_material.TableCell, {}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.TableCell, { + align: "left", + children: (0, _comps.TxtLabel)(classes, 'FG SMARTS', 'txt-prd-table-title') + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.TableCell, { + align: "right", + children: (0, _comps.TxtLabel)(classes, 'Machine Confidence', 'txt-prd-table-title') + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.TableCell, { + align: "right", + children: (0, _comps.TxtLabel)(classes, 'Machine', 'txt-prd-table-title') + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.TableCell, { + align: "right", + children: (0, _comps.TxtLabel)(classes, 'Owner', 'txt-prd-table-title') + })] + }) +}); +exports.IrTableHeader = IrTableHeader; +const colorStyles = [{ + backgroundColor: '#FFFF00' +}, { + backgroundColor: '#87CEFA' +}, { + backgroundColor: '#FFB6C1' +}, { + backgroundColor: '#00FF00' +}, { + backgroundColor: '#E6E6FA' +}, { + backgroundColor: '#FFD700' +}, { + backgroundColor: '#F0FFFF' +}, { + backgroundColor: '#F5F5DC' +}]; +const colorLabel = function colorLabel(classes, idx) { + let extClsName = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'txt-label'; + const style = Object.assign({}, colorStyles[idx % 8], { + width: 20, + borderRadius: 20, + textAlign: 'center' + }); + return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", { + style: style, + children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: (0, _classnames.default)(classes.txtLabel, extClsName), + children: idx + 1 + }) + }); +}; +const IrTableBodyRow = (classes, idx, fg) => /*#__PURE__*/(0, _jsxRuntime.jsxs)(_material.TableRow, { + children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_material.TableCell, { + component: "th", + scope: "row", + children: colorLabel(classes, idx) + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.TableCell, { + align: "left", + children: (0, _comps.TxtLabel)(classes, fg.sma, 'txt-prd-table-content') + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.TableCell, { + align: "right", + children: (0, _comps.ConfidenceLabel)(classes, fg.confidence, 'txt-prd-table-content') + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.TableCell, { + align: "right", + children: (0, _comps.StatusIcon)(fg.status) + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.TableCell, { + align: "right", + children: /*#__PURE__*/(0, _jsxRuntime.jsx)(SelectIrStatus, { + sma: fg.sma, + status: fg.statusOwner, + identity: "Owner" + }) + })] +}, `${idx}-${fg.name}`); +exports.IrTableBodyRow = IrTableBodyRow; \ No newline at end of file diff --git a/dist/components/forecast/ir_viewer.js b/dist/components/forecast/ir_viewer.js new file mode 100644 index 00000000..c9951a50 --- /dev/null +++ b/dist/components/forecast/ir_viewer.js @@ -0,0 +1,141 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; +var _react = _interopRequireDefault(require("react")); +var _propTypes = _interopRequireDefault(require("prop-types")); +var _classnames = _interopRequireDefault(require("classnames")); +var _reactRedux = require("react-redux"); +var _redux = require("redux"); +var _styles = require("@mui/styles"); +var _material = require("@mui/material"); +var _comps = require("./comps"); +var _ir_comps = require("./ir_comps"); +var _jsxRuntime = require("react/jsx-runtime"); +const Styles = () => ({ + root: { + overflowX: 'hidden', + overflowY: 'auto' + }, + container: { + minHeight: '400px' + }, + svgRoot: { + margin: '10px 40px 0px 40px', + height: 'calc(70vh)', + overflowY: 'hidden' + }, + tableRoot: { + margin: '10px 40px 0px 40px', + maxHeight: 'calc(70vh)', + overflowY: 'scroll' + }, + title: { + textAlign: 'left' + }, + btn: { + marginLeft: 40 + }, + reference: { + borderTop: '1px solid #cfd8dc', + margin: '10px 40px 0px 40px', + padding: 5 + }, + inputRoot: { + margin: '10px 40px 0px 40px' + }, + txtLabel: { + fontSize: '12px' + }, + submit: { + margin: '0 0 0 30px', + width: 300 + } +}); +const sectionTable = (classes, pds) => { + const renderMsg = (0, _comps.notToRenderAnalysis)(pds); + if (renderMsg) return renderMsg; + if (!pds.output.result || !pds.output.result[0]) return null; + const { + fgs + } = pds.output.result[0]; + if (!fgs) return null; + return /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Paper, { + className: classes.tableRoot, + children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_material.Table, { + className: classes.table, + size: "small", + children: [(0, _ir_comps.IrTableHeader)(classes), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.TableBody, { + children: fgs.sort((a, b) => b.confidence - a.confidence).map((fg, idx) => (0, _ir_comps.IrTableBodyRow)(classes, idx, fg)) + })] + }) + }); +}; +const IrViewer = _ref => { + let { + // eslint-disable-line + classes, + molecule, + inputCb, + forecastSt, + curveSt + } = _ref; + const { + curveIdx + } = curveSt; + const predictionsByCurve = forecastSt.predictionsByCurve || {}; + const hasCurvePredictions = Object.prototype.hasOwnProperty.call(predictionsByCurve, curveIdx); + const hasAnyCurvePredictions = Object.keys(predictionsByCurve).length > 0; + const emptyPredictions = { + outline: {}, + output: { + result: [] + } + }; + let activePredictions = forecastSt.predictions; + if (hasCurvePredictions) { + activePredictions = predictionsByCurve[curveIdx]; + } else if (hasAnyCurvePredictions) { + activePredictions = emptyPredictions; + } + return /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", { + className: (0, _classnames.default)(classes.root, 'card-forecast-viewer'), + children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_material.Grid, { + className: (0, _classnames.default)(classes.container), + container: true, + children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Grid, { + item: true, + xs: 4, + children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Paper, { + className: classes.svgRoot, + children: (0, _comps.sectionSvg)(classes, activePredictions) + }) + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Grid, { + item: true, + xs: 8, + children: sectionTable(classes, activePredictions) + })] + }), (0, _comps.sectionInput)(classes, molecule, inputCb)] + }); +}; +const mapStateToProps = (state, props) => ( +// eslint-disable-line +{ + forecastSt: state.forecast, + curveSt: state.curve +}); +const mapDispatchToProps = dispatch => (0, _redux.bindActionCreators)({}, dispatch); +IrViewer.propTypes = { + classes: _propTypes.default.object.isRequired, + molecule: _propTypes.default.string.isRequired, + inputCb: _propTypes.default.oneOfType([_propTypes.default.func, _propTypes.default.bool]), + forecastSt: _propTypes.default.object.isRequired, + curveSt: _propTypes.default.object.isRequired +}; +IrViewer.defaultProps = { + inputCb: false +}; +var _default = exports.default = (0, _redux.compose)((0, _reactRedux.connect)(mapStateToProps, mapDispatchToProps), (0, _styles.withStyles)(Styles))(IrViewer); \ No newline at end of file diff --git a/dist/components/forecast/nmr_comps.js b/dist/components/forecast/nmr_comps.js new file mode 100644 index 00000000..d449e90d --- /dev/null +++ b/dist/components/forecast/nmr_comps.js @@ -0,0 +1,162 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.SectionReference = exports.NmrTableHeader = exports.NmrTableBodyRow = void 0; +var _react = _interopRequireDefault(require("react")); +var _propTypes = _interopRequireDefault(require("prop-types")); +var _classnames = _interopRequireDefault(require("classnames")); +var _reactRedux = require("react-redux"); +var _redux = require("redux"); +var _material = require("@mui/material"); +var _CheckCircleOutline = _interopRequireDefault(require("@mui/icons-material/CheckCircleOutline")); +var _HighlightOff = _interopRequireDefault(require("@mui/icons-material/HighlightOff")); +var _comps = require("./comps"); +var _forecast = require("../../actions/forecast"); +var _jsxRuntime = require("react/jsx-runtime"); +/* eslint-disable react/function-component-definition, react/destructuring-assignment */ + +const baseSelectNmrStatus = _ref => { + let { + // eslint-disable-line + idx, + atom, + status, + identity, + curveIdx, + setNmrStatusAct + } = _ref; + const theStatus = ['accept', 'reject'].includes(status) ? status : ''; + return /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.FormControl, { + children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_material.Select, { + value: theStatus, + onChange: e => { + setNmrStatusAct({ + predictions: { + idx, + atom, + identity, + value: e.target.value + }, + svgs: [], + curveIdx + }); + }, + children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_material.MenuItem, { + value: "accept", + children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_CheckCircleOutline.default, { + style: { + color: '#4caf50' + } + }) + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.MenuItem, { + value: "reject", + children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_HighlightOff.default, { + style: { + color: '#e91e63' + } + }) + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.MenuItem, { + value: "", + children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", {}) + })] + }) + }); +}; +const bssMapStateToProps = (state, props) => ( +// eslint-disable-line +{ + curveIdx: state.curve.curveIdx +}); +const bssMapDispatchToProps = dispatch => (0, _redux.bindActionCreators)({ + setNmrStatusAct: _forecast.setNmrStatus +}, dispatch); +baseSelectNmrStatus.propTypes = { + idx: _propTypes.default.number.isRequired, + atom: _propTypes.default.number.isRequired, + status: _propTypes.default.string, + identity: _propTypes.default.string.isRequired, + curveIdx: _propTypes.default.number.isRequired, + setNmrStatusAct: _propTypes.default.func.isRequired +}; +baseSelectNmrStatus.defaultProps = { + status: '' +}; +const SelectNmrStatus = (0, _reactRedux.connect)( +// eslint-disable-line +bssMapStateToProps, bssMapDispatchToProps)(baseSelectNmrStatus); // eslint-disable-line + +const numFormat = input => parseFloat(input).toFixed(2); +const realFormat = (val, status) => { + if (status === 'missing') { + return '- - -'; + } + return numFormat(val); +}; +const NmrTableHeader = classes => /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.TableHead, { + children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_material.TableRow, { + children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_material.TableCell, { + children: (0, _comps.TxtLabel)(classes, 'Atom', 'txt-prd-table-title') + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.TableCell, { + align: "right", + children: (0, _comps.TxtLabel)(classes, 'Prediction (ppm)', 'txt-prd-table-title') + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.TableCell, { + align: "right", + children: (0, _comps.TxtLabel)(classes, 'Real (ppm)', 'txt-prd-table-title') + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.TableCell, { + align: "right", + children: (0, _comps.TxtLabel)(classes, 'Diff (ppm)', 'txt-prd-table-title') + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.TableCell, { + align: "right", + children: (0, _comps.TxtLabel)(classes, 'Machine', 'txt-prd-table-title') + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.TableCell, { + align: "right", + children: (0, _comps.TxtLabel)(classes, 'Owner', 'txt-prd-table-title') + })] + }) +}); +exports.NmrTableHeader = NmrTableHeader; +const NmrTableBodyRow = (classes, row, idx) => /*#__PURE__*/(0, _jsxRuntime.jsxs)(_material.TableRow, { + children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_material.TableCell, { + component: "th", + scope: "row", + children: (0, _comps.TxtLabel)(classes, row.atom, 'txt-prd-table-content') + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.TableCell, { + align: "right", + children: (0, _comps.TxtLabel)(classes, numFormat(row.prediction), 'txt-prd-table-content') + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.TableCell, { + align: "right", + children: (0, _comps.TxtLabel)(classes, realFormat(row.real, row.status), 'txt-prd-table-content') + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.TableCell, { + align: "right", + children: (0, _comps.TxtLabel)(classes, realFormat(row.diff, row.status), 'txt-prd-table-content') + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.TableCell, { + align: "right", + children: (0, _comps.StatusIcon)(row.status) + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.TableCell, { + align: "right", + children: /*#__PURE__*/(0, _jsxRuntime.jsx)(SelectNmrStatus, { + idx: idx, + atom: row.atom, + status: row.statusOwner, + identity: "Owner" + }) + })] +}, `${idx}-${row.atom}`); +exports.NmrTableBodyRow = NmrTableBodyRow; +const SectionReference = classes => /*#__PURE__*/(0, _jsxRuntime.jsx)("div", { + className: (0, _classnames.default)(classes.reference), + children: /*#__PURE__*/(0, _jsxRuntime.jsxs)("p", { + children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + children: "NMR prediction source: " + }), /*#__PURE__*/(0, _jsxRuntime.jsx)("a", { + href: "https://www.ncbi.nlm.nih.gov/pubmed/15464159", + target: "_blank", + rel: "noopener noreferrer", + children: "nmrshiftdb" + })] + }) +}); +exports.SectionReference = SectionReference; \ No newline at end of file diff --git a/dist/components/forecast/nmr_viewer.js b/dist/components/forecast/nmr_viewer.js new file mode 100644 index 00000000..be2e6e83 --- /dev/null +++ b/dist/components/forecast/nmr_viewer.js @@ -0,0 +1,138 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; +var _react = _interopRequireDefault(require("react")); +var _propTypes = _interopRequireDefault(require("prop-types")); +var _classnames = _interopRequireDefault(require("classnames")); +var _reactRedux = require("react-redux"); +var _redux = require("redux"); +var _styles = require("@mui/styles"); +var _material = require("@mui/material"); +var _comps = require("./comps"); +var _nmr_comps = require("./nmr_comps"); +var _jsxRuntime = require("react/jsx-runtime"); +const Styles = () => ({ + root: { + overflowX: 'hidden', + overflowY: 'auto' + }, + container: { + minHeight: '400px' + }, + svgRoot: { + margin: '10px 40px 0px 40px', + height: 'calc(70vh)', + overflowY: 'hidden' + }, + tableRoot: { + margin: '10px 40px 0px 40px', + maxHeight: 'calc(70vh)', + overflowY: 'scroll' + }, + title: { + textAlign: 'left' + }, + btn: { + marginLeft: 40 + }, + reference: { + borderTop: '1px solid #cfd8dc', + margin: '10px 40px 0px 40px', + padding: 5 + }, + inputRoot: { + margin: '10px 40px 0px 40px' + }, + txtLabel: { + fontSize: '12px' + }, + submit: { + margin: '0 0 0 30px', + width: 300 + } +}); +const sectionTable = (classes, pds) => { + const renderMsg = (0, _comps.notToRenderAnalysis)(pds); + if (renderMsg) return renderMsg; + const dict = pds.output.result[0]; + if (!dict) return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {}); + return /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Paper, { + className: classes.tableRoot, + children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_material.Table, { + className: classes.table, + size: "small", + children: [(0, _nmr_comps.NmrTableHeader)(classes), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.TableBody, { + children: dict.shifts.sort((a, b) => a.atom - b.atom).map((row, idx) => (0, _nmr_comps.NmrTableBodyRow)(classes, row, idx)) + })] + }) + }); +}; +const NmrViewer = _ref => { + let { + // eslint-disable-line + classes, + molecule, + inputCb, + forecastSt, + curveSt + } = _ref; + const { + curveIdx + } = curveSt; + const predictionsByCurve = forecastSt.predictionsByCurve || {}; + const hasCurvePredictions = Object.prototype.hasOwnProperty.call(predictionsByCurve, curveIdx); + const hasAnyCurvePredictions = Object.keys(predictionsByCurve).length > 0; + const emptyPredictions = { + outline: {}, + output: { + result: [] + } + }; + let activePredictions = forecastSt.predictions; + if (hasCurvePredictions) { + activePredictions = predictionsByCurve[curveIdx]; + } else if (hasAnyCurvePredictions) { + activePredictions = emptyPredictions; + } + return /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", { + className: (0, _classnames.default)(classes.root, 'card-forecast-viewer'), + children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_material.Grid, { + className: (0, _classnames.default)(classes.container), + container: true, + children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Grid, { + item: true, + xs: 4, + children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Paper, { + className: classes.svgRoot, + children: (0, _comps.sectionSvg)(classes, activePredictions) + }) + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Grid, { + item: true, + xs: 8, + children: sectionTable(classes, activePredictions) + })] + }), (0, _comps.sectionInput)(classes, molecule, inputCb), (0, _nmr_comps.SectionReference)(classes)] + }); +}; +const mapStateToProps = (state, props) => ( +// eslint-disable-line +{ + forecastSt: state.forecast, + curveSt: state.curve +}); +const mapDispatchToProps = dispatch => (0, _redux.bindActionCreators)({}, dispatch); +NmrViewer.propTypes = { + classes: _propTypes.default.object.isRequired, + molecule: _propTypes.default.string.isRequired, + inputCb: _propTypes.default.oneOfType([_propTypes.default.func, _propTypes.default.bool]), + forecastSt: _propTypes.default.object.isRequired, + curveSt: _propTypes.default.object.isRequired +}; +NmrViewer.defaultProps = { + inputCb: false +}; +var _default = exports.default = (0, _redux.compose)((0, _reactRedux.connect)(mapStateToProps, mapDispatchToProps), (0, _styles.withStyles)(Styles))(NmrViewer); \ No newline at end of file diff --git a/dist/components/forecast/section_loading.js b/dist/components/forecast/section_loading.js new file mode 100644 index 00000000..62d38f8d --- /dev/null +++ b/dist/components/forecast/section_loading.js @@ -0,0 +1,62 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; +var _react = _interopRequireDefault(require("react")); +var _CircularProgress = _interopRequireDefault(require("@mui/material/CircularProgress")); +var _ErrorOutline = _interopRequireDefault(require("@mui/icons-material/ErrorOutline")); +var _jsxRuntime = require("react/jsx-runtime"); +const styleLoading = { + alignItems: 'center', + display: 'flex', + height: '100%', + justifyContent: 'center' +}; +class SectionLoading extends _react.default.Component { + constructor(props) { + super(props); + this.state = { + loading: true + }; + } + componentDidMount() { + setTimeout(() => this.setState({ + loading: false + }), 5000); + } + renderLoading() { + return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", { + style: styleLoading, + children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_CircularProgress.default, { + style: { + color: 'blue', + fontSize: 50 + } + }) + }); + } + renderNotFound() { + return /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", { + style: styleLoading, + children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_ErrorOutline.default, { + style: { + color: '#ffc107', + fontSize: 50, + margin: 20 + } + }), /*#__PURE__*/(0, _jsxRuntime.jsx)("h3", { + children: "Structure Not Found" + })] + }); + } + render() { + const { + loading + } = this.state; + return loading ? this.renderLoading() : this.renderNotFound(); + } +} +var _default = exports.default = SectionLoading; \ No newline at end of file diff --git a/dist/components/forecast_viewer.js b/dist/components/forecast_viewer.js new file mode 100644 index 00000000..a702408a --- /dev/null +++ b/dist/components/forecast_viewer.js @@ -0,0 +1,155 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; +var _react = _interopRequireDefault(require("react")); +var _propTypes = _interopRequireDefault(require("prop-types")); +var _reactRedux = require("react-redux"); +var _redux = require("redux"); +var _styles = require("@mui/styles"); +var _index = _interopRequireDefault(require("./d3_line/index")); +var _nmr_viewer = _interopRequireDefault(require("./forecast/nmr_viewer")); +var _ir_viewer = _interopRequireDefault(require("./forecast/ir_viewer")); +var _forecast = require("../actions/forecast"); +var _ui = require("../actions/ui"); +var _list_ui = require("../constants/list_ui"); +var _jsxRuntime = require("react/jsx-runtime"); +/* eslint-disable react/no-unused-prop-types */ + +const styles = () => ({ + root: { + flexGrow: 1 + }, + appBar: { + backgroundColor: '#fff', + boxShadow: 'none' + }, + tabLabel: { + fontSize: '14px' + } +}); +class ForecastViewer extends _react.default.Component { + constructor(props) { + super(props); + this.initForecastReducer = this.initForecastReducer.bind(this); + } + componentDidMount() { + this.initForecastReducer(); + } + componentDidUpdate(prevProps) { + const { + forecast + } = this.props; + const prevForecast = forecast; + const nextForecast = prevProps.forecast; + if (prevForecast !== nextForecast) { + this.initForecastReducer(); + } + } + initForecastReducer() { + const { + forecast, + initForecastStatusAct, + setUiViewerTypeAct + } = this.props; + const predictionCurveIdx = forecast && forecast.predictions && Number.isInteger(forecast.predictions.curveIdx) ? forecast.predictions.curveIdx : null; + const payload = predictionCurveIdx === null ? forecast : { + ...forecast, + curveIdx: predictionCurveIdx + }; + initForecastStatusAct(payload); + if (forecast && forecast.predictions) { + const { + running, + refreshed + } = forecast.predictions; + if (running || refreshed) setUiViewerTypeAct(_list_ui.LIST_UI_VIEWER_TYPE.ANALYSIS); + } + } + render() { + const { + classes, + topic, + feature, + cLabel, + xLabel, + yLabel, + forecast, + isNmr, + isIr, + uiSt, + isXRD, + wavelength, + curveSt, + jcampSt + } = this.props; + const { + viewer + } = uiSt; + const { + inputCb, + molecule + } = forecast; + const { + curveIdx + } = curveSt; + const { + jcamps + } = jcampSt; + const currentJcamp = jcamps && jcamps[curveIdx]; + const comparisons = currentJcamp && currentJcamp.others ? currentJcamp.others : []; + return /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", { + className: classes.root, + children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_index.default, { + topic: topic, + feature: feature, + cLabel: cLabel, + xLabel: isXRD && wavelength ? `${xLabel}, WL=${wavelength.value} ${wavelength.unit}` : xLabel, + yLabel: yLabel, + comparisons: comparisons, + isHidden: viewer !== _list_ui.LIST_UI_VIEWER_TYPE.SPECTRUM + }), viewer === _list_ui.LIST_UI_VIEWER_TYPE.ANALYSIS && isNmr && /*#__PURE__*/(0, _jsxRuntime.jsx)(_nmr_viewer.default, { + molecule: molecule, + inputCb: inputCb + }), viewer === _list_ui.LIST_UI_VIEWER_TYPE.ANALYSIS && isIr && /*#__PURE__*/(0, _jsxRuntime.jsx)(_ir_viewer.default, { + molecule: molecule, + inputCb: inputCb + })] + }); + } +} +const mapStateToProps = (state, _) => ( +// eslint-disable-line +{ + uiSt: state.ui, + jcampSt: state.jcamp, + wavelength: state.wavelength, + curveSt: state.curve +}); +const mapDispatchToProps = dispatch => (0, _redux.bindActionCreators)({ + initForecastStatusAct: _forecast.initForecastStatus, + setUiViewerTypeAct: _ui.setUiViewerType +}, dispatch); +ForecastViewer.propTypes = { + classes: _propTypes.default.object.isRequired, + topic: _propTypes.default.object.isRequired, + feature: _propTypes.default.object.isRequired, + cLabel: _propTypes.default.string.isRequired, + xLabel: _propTypes.default.string.isRequired, + yLabel: _propTypes.default.string.isRequired, + forecast: _propTypes.default.object.isRequired, + isNmr: _propTypes.default.bool.isRequired, + isIr: _propTypes.default.bool.isRequired, + isUvvis: _propTypes.default.bool.isRequired, + isXRD: _propTypes.default.bool.isRequired, + uiSt: _propTypes.default.object.isRequired, + jcampSt: _propTypes.default.object.isRequired, + initForecastStatusAct: _propTypes.default.func.isRequired, + setUiViewerTypeAct: _propTypes.default.func.isRequired, + wavelength: _propTypes.default.object.isRequired, + curveSt: _propTypes.default.object.isRequired +}; +var _default = exports.default = (0, _redux.compose)((0, _reactRedux.connect)(mapStateToProps, mapDispatchToProps), (0, _styles.withStyles)(styles))(ForecastViewer); \ No newline at end of file diff --git a/dist/components/multi_jcamps_viewer.js b/dist/components/multi_jcamps_viewer.js new file mode 100644 index 00000000..43c72963 --- /dev/null +++ b/dist/components/multi_jcamps_viewer.js @@ -0,0 +1,209 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; +var _react = _interopRequireDefault(require("react")); +var _propTypes = _interopRequireDefault(require("prop-types")); +var _reactRedux = require("react-redux"); +var _redux = require("redux"); +var _Grid = _interopRequireDefault(require("@mui/material/Grid")); +var _styles = require("@mui/styles"); +var _index = _interopRequireDefault(require("./panel/index")); +var _index2 = _interopRequireDefault(require("./cmd_bar/index")); +var _index3 = _interopRequireDefault(require("./d3_multi/index")); +var _forecast_viewer = _interopRequireDefault(require("./forecast_viewer")); +var _curve = require("../actions/curve"); +var _cyclic_voltammetry = require("../actions/cyclic_voltammetry"); +var _list_layout = require("../constants/list_layout"); +var _list_ui = require("../constants/list_ui"); +var _format = _interopRequireDefault(require("../helpers/format")); +var _jsxRuntime = require("react/jsx-runtime"); +/* eslint-disable react/default-props-match-prop-types, +react/require-default-props, react/no-unused-prop-types, react/jsx-boolean-value, +prefer-object-spread */ + +const styles = () => ({ + root: { + flexGrow: 1 + }, + appBar: { + backgroundColor: '#fff', + boxShadow: 'none' + }, + tabLabel: { + fontSize: '14px' + } +}); +const seperatingSubLayout = (entities, featureCondition, layoutSt) => { + if (layoutSt === _list_layout.LIST_LAYOUT.CYCLIC_VOLTAMMETRY) { + return null; + } + const storedDict = {}; + entities.forEach(entity => { + const { + feature + } = entity; + const keyValue = feature[featureCondition]; + if (keyValue in storedDict) { + storedDict[keyValue].push(entity); + } else { + storedDict[keyValue] = [entity]; + } + }); + return Object.assign({}, storedDict); +}; +class MultiJcampsViewer extends _react.default.Component { + // eslint-disable-line + render() { + const { + classes, + curveSt, + operations, + entityFileNames, + entities, + userManualLink, + molSvg, + exactMass, + layoutSt, + integrationSt, + descriptions, + canChangeDescription, + onDescriptionChanged, + forecast, + uiSt, + cLabel + } = this.props; + if (!entities || entities.length === 0) return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {}); + const separateCondition = _format.default.isGCLayout(layoutSt) ? 'yUnit' : 'xUnit'; + const seperatedSubLayouts = seperatingSubLayout(entities, separateCondition, layoutSt); + const { + curveIdx + } = curveSt; + const entity = entities[curveIdx]; + const { + feature, + topic + } = entity; + const { + integrations + } = integrationSt; + const currentIntegration = integrations[curveIdx]; + const isNmr = _format.default.isNmrLayout(layoutSt); + const isIr = _format.default.isIrLayout(layoutSt); + const isUvvis = _format.default.isUvVisLayout(layoutSt) || _format.default.isHplcUvVisLayout(layoutSt); + const isXRD = _format.default.isXRDLayout(layoutSt); + const hasForecast = forecast && Object.keys(forecast).length > 0; + const showForecast = hasForecast && (isNmr || isIr || isUvvis || isXRD) && uiSt.viewer === _list_ui.LIST_UI_VIEWER_TYPE.ANALYSIS; + const xLabel = feature.xUnit ? `X (${feature.xUnit})` : ''; + const yLabel = feature.yUnit ? `Y (${feature.yUnit})` : ''; + return /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", { + className: classes.root, + children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_index2.default, { + feature: feature, + operations: operations, + forecast: forecast, + editorOnly: true, + hideThreshold: !_format.default.isNmrLayout(layoutSt) + }), /*#__PURE__*/(0, _jsxRuntime.jsx)("div", { + className: "react-spectrum-editor", + children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_Grid.default, { + container: true, + children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_Grid.default, { + item: true, + xs: 9, + children: showForecast ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_forecast_viewer.default, { + topic: topic, + cLabel: cLabel, + xLabel: xLabel, + yLabel: yLabel, + feature: feature, + forecast: forecast, + isNmr: isNmr, + isIr: isIr, + isUvvis: isUvvis, + isXRD: isXRD + }) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_index3.default, { + entities: entities, + topic: topic, + xLabel: feature.xUnit, + yLabel: feature.yUnit, + feature: feature + }) + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_Grid.default, { + item: true, + xs: 3, + align: "center", + children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_index.default, { + jcampIdx: curveIdx, + entityFileNames: entityFileNames, + userManualLink: userManualLink, + feature: feature, + molSvg: molSvg, + exactMass: exactMass, + subLayoutsInfo: seperatedSubLayouts, + integration: currentIntegration, + descriptions: descriptions, + canChangeDescription: canChangeDescription, + onDescriptionChanged: onDescriptionChanged + }) + })] + }) + })] + }); + } +} +const mapStateToProps = (state, _) => ( +// eslint-disable-line +{ + curveSt: state.curve, + cyclicVoltaSt: state.cyclicvolta, + entities: state.curve.listCurves, + layoutSt: state.layout, + integrationSt: state.integration.present, + uiSt: state.ui +}); +const mapDispatchToProps = dispatch => (0, _redux.bindActionCreators)({ + setAllCurvesAct: _curve.setAllCurves, + addNewCylicVoltaPairPeakAct: _cyclic_voltammetry.addNewCylicVoltaPairPeak, + addCylicVoltaMaxPeakAct: _cyclic_voltammetry.addCylicVoltaMaxPeak, + addCylicVoltaMinPeakAct: _cyclic_voltammetry.addCylicVoltaMinPeak, + addCylicVoltaPeckerAct: _cyclic_voltammetry.addCylicVoltaPecker +}, dispatch); +MultiJcampsViewer.propTypes = { + classes: _propTypes.default.object.isRequired, + multiEntities: _propTypes.default.array.isRequired, + entityFileNames: _propTypes.default.array.isRequired, + molSvg: _propTypes.default.string.isRequired, + setAllCurvesAct: _propTypes.default.func.isRequired, + curveSt: _propTypes.default.object.isRequired, + cyclicVoltaSt: _propTypes.default.object.isRequired, + addNewCylicVoltaPairPeakAct: _propTypes.default.func.isRequired, + addCylicVoltaMaxPeakAct: _propTypes.default.func.isRequired, + addCylicVoltaMinPeakAct: _propTypes.default.func.isRequired, + operations: _propTypes.default.func.isRequired, + userManualLink: _propTypes.default.object, + entities: _propTypes.default.array, + layoutSt: _propTypes.default.string.isRequired, + exactMass: _propTypes.default.string, + integrationSt: _propTypes.default.object.isRequired, + descriptions: _propTypes.default.array.isRequired, + canChangeDescription: _propTypes.default.bool.isRequired, + onDescriptionChanged: _propTypes.default.func, + forecast: _propTypes.default.object.isRequired, + uiSt: _propTypes.default.object.isRequired, + cLabel: _propTypes.default.string +}; +MultiJcampsViewer.defaultProps = { + multiEntities: [], + entityFileNames: [], + molSvg: '', + entities: [], + descriptions: [], + canChangeDescription: false, + forecast: {}, + cLabel: '' +}; +var _default = exports.default = (0, _redux.compose)((0, _reactRedux.connect)(mapStateToProps, mapDispatchToProps), (0, _styles.withStyles)(styles))(MultiJcampsViewer); \ No newline at end of file diff --git a/dist/components/panel/compare.js b/dist/components/panel/compare.js new file mode 100644 index 00000000..3d36c851 --- /dev/null +++ b/dist/components/panel/compare.js @@ -0,0 +1,278 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; +var _react = _interopRequireDefault(require("react")); +var _propTypes = _interopRequireDefault(require("prop-types")); +var _classnames = _interopRequireDefault(require("classnames")); +var _reactRedux = require("react-redux"); +var _redux = require("redux"); +var _reactDropzone = _interopRequireDefault(require("react-dropzone")); +var _material = require("@mui/material"); +var _ExpandMore = _interopRequireDefault(require("@mui/icons-material/ExpandMore")); +var _HighlightOff = _interopRequireDefault(require("@mui/icons-material/HighlightOff")); +var _VisibilityOutlined = _interopRequireDefault(require("@mui/icons-material/VisibilityOutlined")); +var _VisibilityOffOutlined = _interopRequireDefault(require("@mui/icons-material/VisibilityOffOutlined")); +var _styles = require("@mui/styles"); +var _format = _interopRequireDefault(require("../../helpers/format")); +var _jcamp = require("../../actions/jcamp"); +var _jsxRuntime = require("react/jsx-runtime"); +/* eslint-disable function-paren-newline, react/jsx-props-no-spreading, +react/function-component-definition */ + +const styles = theme => ({ + panel: { + backgroundColor: '#eee', + display: 'table-row' + }, + panelSummary: { + backgroundColor: '#eee', + height: 32 + }, + txtBadge: {}, + panelDetail: { + backgroundColor: '#fff', + maxHeight: 'calc(90vh - 220px)', + // ROI + overflow: 'auto' + }, + table: { + width: '100%' + }, + tTxt: { + padding: 0 + }, + tTxtHide: { + color: '#D5D8DC' + }, + tRow: { + height: 28, + '&:nth-of-type(even)': { + backgroundColor: theme.palette ? theme.palette.background.default : '#d3d3d3' + } + }, + rmBtn: { + color: 'red', + padding: '0 5px 0 5px', + '&:hover': { + borderRadius: 12, + backgroundColor: 'red', + color: 'white' + } + }, + showBtn: { + color: 'steelblue', + padding: '0 5px 0 5px', + '&:hover': { + borderRadius: 12, + backgroundColor: 'steelblue', + color: 'white' + } + }, + hideBtn: { + color: 'gray', + padding: '0 5px 0 5px', + '&:hover': { + borderRadius: 12, + backgroundColor: 'gray', + color: 'white' + } + }, + square: { + textAlign: 'center !important' + }, + baseDD: { + backgroundColor: 'white', + border: '1px dashed black', + borderRadius: 5, + height: 26, + lineHeight: '26px', + margin: '7px 0 7px 0', + textAlign: 'center', + verticalAlign: 'middle', + width: '90%' + }, + enableDD: { + border: '2px dashed #000', + color: '#000' + }, + disableDD: { + border: '2px dashed #aaa', + color: '#aaa' + }, + tpCard: {}, + tpMoreTxt: { + padding: '0 0 0 60px' + }, + tpLabel: { + fontSize: 16 + } +}); +const msgDefault = 'Add spectra to compare.'; +const tpHint = classes => /*#__PURE__*/(0, _jsxRuntime.jsxs)("span", { + className: (0, _classnames.default)(classes.tpCard), + children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("p", { + className: (0, _classnames.default)(classes.tpLabel, 'txt-sv-tp'), + children: "- Accept *.dx, *.jdx, *.JCAMP," + }), /*#__PURE__*/(0, _jsxRuntime.jsx)("p", { + className: (0, _classnames.default)(classes.tpLabel, 'txt-sv-tp'), + children: "- Max 5 spectra." + })] +}); +const content = (classes, desc) => /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Tooltip, { + title: tpHint(classes), + placement: "bottom", + children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: (0, _classnames.default)(classes.tpLabel, 'txt-sv-tp'), + children: desc + }) +}); +const inputOthers = (classes, jcampSt) => { + const { + selectedIdx, + jcamps + } = jcampSt; + const selectedJcamp = jcamps[selectedIdx]; + const { + addOthersCb + } = selectedJcamp; + const fileName = ''; + const desc = fileName || msgDefault; + const onDrop = jcampFiles => { + if (!addOthersCb) return; + addOthersCb({ + jcamps: jcampFiles + }); + }; + return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactDropzone.default, { + className: "dropbox", + onDrop: onDrop, + children: _ref => { + let { + getRootProps, + getInputProps + } = _ref; + return /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", { + ...getRootProps(), + className: (0, _classnames.default)(classes.baseDD), + children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("input", { + ...getInputProps() + }), content(classes, desc)] + }); + } + }); +}; +const compareList = (classes, jcampSt, rmOthersOneAct, toggleShowAct) => { + const { + selectedIdx, + jcamps + } = jcampSt; + const selectedJcamp = jcamps[selectedIdx]; + const { + others + } = selectedJcamp; + const rows = others.map((o, idx) => ({ + idx, + title: o.spectra[0].title, + color: _format.default.compareColors(idx), + rmCb: () => rmOthersOneAct(idx), + isShow: o.show, + toggleShowCb: () => toggleShowAct(idx) + })); + return /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Table, { + className: classes.table, + children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.TableBody, { + children: rows.map(row => /*#__PURE__*/(0, _jsxRuntime.jsxs)(_material.TableRow, { + className: classes.tRow, + hover: true, + children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_material.TableCell, { + align: "right", + className: (0, _classnames.default)(classes.tTxt, classes.square, 'txt-sv-panel-txt'), + style: { + backgroundColor: row.color + }, + children: row.idx + 1 + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.TableCell, { + align: "right", + className: (0, _classnames.default)(classes.tTxt, 'txt-sv-panel-txt', row.isShow ? null : classes.tTxtHide), + children: row.title + }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_material.TableCell, { + align: "right", + className: (0, _classnames.default)(classes.tTxt, 'txt-sv-panel-txt'), + children: [row.isShow ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_VisibilityOutlined.default, { + onClick: row.toggleShowCb, + className: classes.showBtn + }) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_VisibilityOffOutlined.default, { + onClick: row.toggleShowCb, + className: classes.hideBtn + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_HighlightOff.default, { + onClick: row.rmCb, + className: classes.rmBtn + })] + })] + }, row.idx)) + }) + }); +}; +const ComparePanel = _ref2 => { + let { + classes, + expand, + onExapnd, + jcampSt, + rmOthersOneAct, + toggleShowAct + } = _ref2; + return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_material.Accordion, { + expanded: expand, + onChange: onExapnd, + disableGutters: true, + sx: { + '&.MuiAccordion-root.Mui-expanded': { + margin: 0 + }, + '&:before': { + display: 'none' + } + }, + TransitionProps: { + unmountOnExit: true + } // increase Accordion performance + , + children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_material.AccordionSummary, { + expandIcon: /*#__PURE__*/(0, _jsxRuntime.jsx)(_ExpandMore.default, {}), + className: (0, _classnames.default)(classes.panelSummary), + children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Typography, { + className: "txt-panel-header", + children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: (0, _classnames.default)(classes.txtBadge, 'txt-sv-panel-title'), + children: "Spectra Comparisons" + }) + }) + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Divider, {}), inputOthers(classes, jcampSt), /*#__PURE__*/(0, _jsxRuntime.jsx)("div", { + className: (0, _classnames.default)(classes.panelDetail), + children: compareList(classes, jcampSt, rmOthersOneAct, toggleShowAct) + })] + }); +}; +const mapStateToProps = (state, props) => ( +// eslint-disable-line +{ + jcampSt: state.jcamp +}); +const mapDispatchToProps = dispatch => (0, _redux.bindActionCreators)({ + rmOthersOneAct: _jcamp.rmOthersOne, + toggleShowAct: _jcamp.toggleShow +}, dispatch); +ComparePanel.propTypes = { + classes: _propTypes.default.object.isRequired, + expand: _propTypes.default.bool.isRequired, + onExapnd: _propTypes.default.func.isRequired, + jcampSt: _propTypes.default.object.isRequired, + rmOthersOneAct: _propTypes.default.func.isRequired, + toggleShowAct: _propTypes.default.func.isRequired +}; +var _default = exports.default = (0, _reactRedux.connect)(mapStateToProps, mapDispatchToProps)((0, _styles.withStyles)(styles)(ComparePanel)); \ No newline at end of file diff --git a/dist/components/panel/cyclic_voltamery_data.js b/dist/components/panel/cyclic_voltamery_data.js new file mode 100644 index 00000000..315f188f --- /dev/null +++ b/dist/components/panel/cyclic_voltamery_data.js @@ -0,0 +1,377 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; +var _react = _interopRequireDefault(require("react")); +var _propTypes = _interopRequireDefault(require("prop-types")); +var _classnames = _interopRequireDefault(require("classnames")); +var _reactRedux = require("react-redux"); +var _redux = require("redux"); +var _ExpandMore = _interopRequireDefault(require("@mui/icons-material/ExpandMore")); +var _AddCircleOutline = _interopRequireDefault(require("@mui/icons-material/AddCircleOutline")); +var _RemoveCircle = _interopRequireDefault(require("@mui/icons-material/RemoveCircle")); +var _Info = _interopRequireDefault(require("@mui/icons-material/Info")); +var _Help = _interopRequireDefault(require("@mui/icons-material/Help")); +var _styles = require("@mui/styles"); +var _material = require("@mui/material"); +var _cyclic_voltammetry = require("../../actions/cyclic_voltammetry"); +var _ui = require("../../actions/ui"); +var _list_ui = require("../../constants/list_ui"); +var _chem = require("../../helpers/chem"); +var _format = _interopRequireDefault(require("../../helpers/format")); +var _jsxRuntime = require("react/jsx-runtime"); +/* eslint-disable function-paren-newline, react/require-default-props, +react/no-unused-prop-types, react/jsx-closing-tag-location, max-len, react/jsx-one-expression-per-line, +react/jsx-indent, react/no-unescaped-entities, react/jsx-wrap-multilines, camelcase, no-shadow, +arrow-body-style, react/function-component-definition */ + +const styles = () => ({ + panel: { + backgroundColor: '#eee', + display: 'table-row' + }, + panelSummary: { + backgroundColor: '#eee', + height: 32 + }, + panelDetail: { + backgroundColor: '#fff', + maxHeight: 'calc(90vh - 220px)', + // ROI + overflow: 'auto' + }, + table: { + width: '100%', + overflowWrap: 'anywhere', + fontSize: '14px !important' + }, + td: { + wordWrap: 'break-all', + fontSize: '14px !important' + }, + cellSelected: { + backgroundColor: '#2196f3', + color: '#fff', + fontSize: '14px !important' + }, + btnRemove: { + color: 'red' + }, + btnAddRow: { + color: 'green' + }, + tTxt: { + padding: 5 + }, + infoIcon: { + width: '15px', + height: '16px' + }, + txtToolTip: { + lineHeight: 'normal !important', + fontSize: '14px !important' + }, + rowRoot: { + border: '1px solid #eee', + height: 36, + lineHeight: '36px', + overflow: 'hidden', + paddingLeft: 24, + textAlign: 'left' + }, + rowOdd: { + backgroundColor: '#fff', + textOverflow: 'ellipsis', + whiteSpace: 'nowrap' + }, + rowEven: { + backgroundColor: '#fafafa', + textOverflow: 'ellipsis', + whiteSpace: 'nowrap' + } +}); +const CyclicVoltammetryPanel = _ref => { + let { + classes, + cyclicVotaSt, + feature, + addNewPairPeakAct, + setWorkWithMaxPeakAct, + selectPairPeakAct, + removePairPeakAct, + selectRefPeaksAct, + sweepTypeSt, + setUiSweepTypeAct, + jcampIdx, + userManualLink + } = _ref; + const { + spectraList + } = cyclicVotaSt; + const spectra = spectraList[jcampIdx]; + let list = []; + if (spectra !== undefined) { + list = spectra.list; + } + const selectCell = (idx, isMax) => { + setWorkWithMaxPeakAct({ + isMax, + jcampIdx + }); + selectPairPeakAct({ + index: idx, + jcampIdx + }); + if (sweepTypeSt === _list_ui.LIST_UI_SWEEP_TYPE.CYCLIC_VOLTA_ADD_MAX_PEAK || sweepTypeSt === _list_ui.LIST_UI_SWEEP_TYPE.CYCLIC_VOLTA_ADD_MIN_PEAK) { + if (isMax) { + setUiSweepTypeAct(_list_ui.LIST_UI_SWEEP_TYPE.CYCLIC_VOLTA_ADD_MAX_PEAK, jcampIdx); + } else { + setUiSweepTypeAct(_list_ui.LIST_UI_SWEEP_TYPE.CYCLIC_VOLTA_ADD_MIN_PEAK, jcampIdx); + } + } else if (sweepTypeSt === _list_ui.LIST_UI_SWEEP_TYPE.CYCLIC_VOLTA_RM_MAX_PEAK || sweepTypeSt === _list_ui.LIST_UI_SWEEP_TYPE.CYCLIC_VOLTA_RM_MIN_PEAK) { + if (isMax) { + setUiSweepTypeAct(_list_ui.LIST_UI_SWEEP_TYPE.CYCLIC_VOLTA_RM_MAX_PEAK, jcampIdx); + } else { + setUiSweepTypeAct(_list_ui.LIST_UI_SWEEP_TYPE.CYCLIC_VOLTA_RM_MIN_PEAK, jcampIdx); + } + } + }; + const changeCheckRefPeaks = (idx, event) => { + selectRefPeaksAct({ + index: idx, + jcampIdx, + checked: event.target.checked + }); + }; + const getDelta = data => { + return data.max && data.min ? _format.default.strNumberFixedLength((0, _chem.GetCyclicVoltaPeakSeparate)(data.max.x, data.min.x) * 1000, 3) : 'nd'; + }; + const getRatio = (feature, data) => { + const featureData = feature.data[0]; + const idx = featureData.x.indexOf(feature.maxX); + const y_pecker = data.pecker ? data.pecker.y : featureData.y[idx]; + return data.max && data.min ? _format.default.strNumberFixedLength((0, _chem.GetCyclicVoltaRatio)(data.max.y, data.min.y, y_pecker), 3) : 'nd'; + }; + const rows = list.map((o, idx) => ({ + idx, + max: o.max ? `E: ${_format.default.strNumberFixedLength(parseFloat(o.max.x), 3)} V,\nI: ${parseFloat(o.max.y * 1000).toExponential(2)} mA` : 'nd', + min: o.min ? `E: ${_format.default.strNumberFixedLength(parseFloat(o.min.x), 3)} V,\nI: ${parseFloat(o.min.y * 1000).toExponential(2)} mA` : 'nd', + pecker: o.pecker ? `${parseFloat(o.pecker.y * 1000).toExponential(2)} mA` : 'nd', + delta: `${getDelta(o)} mV`, + ratio: getRatio(feature, o), + e12: typeof o.e12 === 'number' ? `${_format.default.strNumberFixedLength(o.e12, 3)} V` : 'nd', + isRef: o.isRef, + onClickMax: () => selectCell(idx, true), + onClickMin: () => selectCell(idx, false), + remove: () => removePairPeakAct({ + index: idx, + jcampIdx + }), + onCheckRefChanged: e => changeCheckRefPeaks(idx, e) + })); + return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_material.Accordion, { + "data-testid": "PanelVoltammetry", + disableGutters: true, + sx: { + '&.MuiAccordion-root.Mui-expanded': { + margin: 0 + }, + '&:before': { + display: 'none' + } + }, + children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_material.AccordionSummary, { + expandIcon: /*#__PURE__*/(0, _jsxRuntime.jsx)(_ExpandMore.default, {}), + className: (0, _classnames.default)(classes.panelSummary), + children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Typography, { + className: "txt-panel-header", + children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: (0, _classnames.default)(classes.txtBadge, 'txt-sv-panel-title'), + children: "Voltammetry data" + }) + }) + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Divider, {}), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_material.Table, { + className: classes.table, + children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_material.TableHead, { + children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_material.TableRow, { + children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_material.TableCell, { + align: "left", + className: (0, _classnames.default)(classes.tTxt, classes.square, 'txt-sv-panel-txt'), + children: "Ref" + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.TableCell, { + align: "left", + className: (0, _classnames.default)(classes.tTxt, classes.square, 'txt-sv-panel-txt'), + children: "Anodic" + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.TableCell, { + align: "left", + className: (0, _classnames.default)(classes.tTxt, classes.square, 'txt-sv-panel-txt'), + children: "Cathodic" + }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_material.TableCell, { + align: "left", + className: (0, _classnames.default)(classes.tTxt, classes.square, 'txt-sv-panel-txt'), + children: ["I ", /*#__PURE__*/(0, _jsxRuntime.jsx)("sub", { + children: "\u03BB0" + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Tooltip, { + title: /*#__PURE__*/(0, _jsxRuntime.jsxs)("p", { + className: (0, _classnames.default)(classes.txtToolTip), + children: ["Baseline correction value for I ratio ", /*#__PURE__*/(0, _jsxRuntime.jsx)("br", {}), "(a.k.a y value of pecker)"] + }), + children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Info.default, { + className: (0, _classnames.default)(classes.infoIcon) + }) + })] + }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_material.TableCell, { + align: "left", + className: (0, _classnames.default)(classes.tTxt, classes.square, 'txt-sv-panel-txt'), + children: ["I ratio", /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Tooltip, { + title: /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", { + className: (0, _classnames.default)(classes.txtToolTip), + children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("p", { + children: "Nicholson's method" + }), /*#__PURE__*/(0, _jsxRuntime.jsx)("i", { + children: "NICHOLSON, Rl S. Semiempirical Procedure for Measuring with Stationary Electrode Polarography Rates of Chemical Reactions Involving the Product of Electron Transfer. Analytical Chemistry, 1966, 38. Jg., Nr. 10, S. 1406-1406. https://doi.org/10.1021/ac60242a030" + })] + }), + children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Info.default, { + className: (0, _classnames.default)(classes.infoIcon) + }) + })] + }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_material.TableCell, { + align: "left", + className: (0, _classnames.default)(classes.tTxt, classes.square, 'txt-sv-panel-txt'), + children: ["E", /*#__PURE__*/(0, _jsxRuntime.jsx)("sub", { + children: "1/2" + })] + }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_material.TableCell, { + align: "left", + className: (0, _classnames.default)(classes.tTxt, classes.square, 'txt-sv-panel-txt'), + children: ["\u0394E", /*#__PURE__*/(0, _jsxRuntime.jsx)("sub", { + children: "p" + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Tooltip, { + title: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: (0, _classnames.default)(classes.txtToolTip), + children: "| Epa - Epc |" + }), + children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Info.default, { + className: (0, _classnames.default)(classes.infoIcon) + }) + })] + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.TableCell, { + align: "left", + className: (0, _classnames.default)(classes.tTxt, classes.square, 'txt-sv-panel-txt'), + children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_AddCircleOutline.default, { + onClick: () => addNewPairPeakAct(jcampIdx), + className: (0, _classnames.default)(classes.btnAddRow) + }) + })] + }) + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.TableBody, { + children: rows.map(row => /*#__PURE__*/(0, _jsxRuntime.jsxs)(_material.TableRow, { + children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_material.TableCell, { + align: "left", + className: (0, _classnames.default)(classes.tTxt, classes.square, 'txt-sv-panel-txt'), + children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Checkbox, { + checked: row.isRef, + onChange: row.onCheckRefChanged + }) + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.TableCell, { + align: "left", + className: (0, _classnames.default)(classes.tTxt, classes.square, spectra.isWorkMaxPeak && spectra.selectedIdx === row.idx ? classes.cellSelected : 'txt-sv-panel-txt'), + onClick: row.onClickMax, + children: row.max.split('\n').map((s, index) => /*#__PURE__*/(0, _jsxRuntime.jsxs)(_react.default.Fragment, { + children: [s, /*#__PURE__*/(0, _jsxRuntime.jsx)("br", {})] + }, index)) + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.TableCell, { + align: "left", + className: (0, _classnames.default)(classes.tTxt, classes.square, !spectra.isWorkMaxPeak && spectra.selectedIdx === row.idx ? classes.cellSelected : 'txt-sv-panel-txt'), + onClick: row.onClickMin, + children: row.min.split('\n').map((s, index) => /*#__PURE__*/(0, _jsxRuntime.jsxs)(_react.default.Fragment, { + children: [s, /*#__PURE__*/(0, _jsxRuntime.jsx)("br", {})] + }, index)) + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.TableCell, { + align: "left", + className: (0, _classnames.default)(classes.tTxt, classes.square, 'txt-sv-panel-txt'), + children: row.pecker + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.TableCell, { + align: "left", + className: (0, _classnames.default)(classes.tTxt, classes.square, 'txt-sv-panel-txt'), + children: row.ratio + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.TableCell, { + align: "left", + className: (0, _classnames.default)(classes.tTxt, classes.square, 'txt-sv-panel-txt'), + children: row.e12 + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.TableCell, { + align: "left", + className: (0, _classnames.default)(classes.tTxt, classes.square, 'txt-sv-panel-txt'), + children: row.delta + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.TableCell, { + align: "left", + className: (0, _classnames.default)(classes.tTxt, classes.square, 'txt-sv-panel-txt'), + children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_RemoveCircle.default, { + className: (0, _classnames.default)(classes.btnRemove), + onClick: row.remove + }) + })] + }, row.idx)) + })] + }), /*#__PURE__*/(0, _jsxRuntime.jsx)("div", { + className: (0, _classnames.default)(classes.rowRoot, classes.rowEven), + children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Tooltip, { + title: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: (0, _classnames.default)(classes.txtToolTip), + children: "Click here to open the User manual document" + }), + children: /*#__PURE__*/(0, _jsxRuntime.jsxs)("span", { + children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("a", { + target: "_blank", + rel: "noopener noreferrer", + href: userManualLink, + children: "How-To " + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_Help.default, { + className: (0, _classnames.default)(classes.infoIcon) + })] + }) + }) + })] + }); +}; +const mapStateToProps = (state, props) => ( +// eslint-disable-line +{ + layoutSt: state.layout, + cyclicVotaSt: state.cyclicvolta, + sweepTypeSt: state.ui.sweepType +}); +const mapDispatchToProps = dispatch => (0, _redux.bindActionCreators)({ + addNewPairPeakAct: _cyclic_voltammetry.addNewCylicVoltaPairPeak, + setWorkWithMaxPeakAct: _cyclic_voltammetry.setWorkWithMaxPeak, + selectPairPeakAct: _cyclic_voltammetry.selectPairPeak, + removePairPeakAct: _cyclic_voltammetry.removeCylicVoltaPairPeak, + selectRefPeaksAct: _cyclic_voltammetry.selectRefPeaks, + setUiSweepTypeAct: _ui.setUiSweepType +}, dispatch); +CyclicVoltammetryPanel.propTypes = { + classes: _propTypes.default.object.isRequired, + expand: _propTypes.default.bool.isRequired, + feature: _propTypes.default.object.isRequired, + molSvg: _propTypes.default.string.isRequired, + layoutSt: _propTypes.default.string.isRequired, + onExapnd: _propTypes.default.func.isRequired, + cyclicVotaSt: _propTypes.default.object.isRequired, + addNewPairPeakAct: _propTypes.default.func.isRequired, + setWorkWithMaxPeakAct: _propTypes.default.func.isRequired, + selectPairPeakAct: _propTypes.default.func.isRequired, + removePairPeakAct: _propTypes.default.func.isRequired, + selectRefPeaksAct: _propTypes.default.func.isRequired, + setUiSweepTypeAct: _propTypes.default.func.isRequired, + sweepTypeSt: _propTypes.default.string.isRequired, + userManualLink: _propTypes.default.string, + jcampIdx: _propTypes.default.number +}; +CyclicVoltammetryPanel.defaultProps = { + jcampIdx: 0 +}; +var _default = exports.default = (0, _reactRedux.connect)(mapStateToProps, mapDispatchToProps)((0, _styles.withStyles)(styles)(CyclicVoltammetryPanel)); \ No newline at end of file diff --git a/dist/components/panel/graph_selection.js b/dist/components/panel/graph_selection.js new file mode 100644 index 00000000..ed71dce2 --- /dev/null +++ b/dist/components/panel/graph_selection.js @@ -0,0 +1,262 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; +var _react = _interopRequireWildcard(require("react")); +var _propTypes = _interopRequireDefault(require("prop-types")); +var _classnames = _interopRequireDefault(require("classnames")); +var _reactRedux = require("react-redux"); +var _redux = require("redux"); +var _ExpandMore = _interopRequireDefault(require("@mui/icons-material/ExpandMore")); +var _styles = require("@mui/styles"); +var _material = require("@mui/material"); +var _curve = require("../../actions/curve"); +var _list_layout = require("../../constants/list_layout"); +var _jsxRuntime = require("react/jsx-runtime"); +function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); } +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; } +/* eslint-disable react/function-component-definition, function-paren-newline, +react/require-default-props, react/no-unused-prop-types */ + +const styles = () => ({ + panelSummary: { + backgroundColor: '#eee', + height: 22 + }, + curve: { + width: '100%' + }, + line: { + height: '2px', + borderWidth: '0', + margin: '0' + }, + curveDefault: { + backgroundColor: '#fff', + fontSize: '0.8em', + margin: '0', + padding: '10px 2px 2px 10px', + maxWidth: '95%', + overflowWrap: 'anywhere' + }, + curveSelected: { + backgroundColor: '#2196f3', + fontSize: '0.8em', + color: '#fff', + padding: '10px 2px 2px 10px', + maxWidth: '95%', + overflowWrap: 'anywhere' + } +}); +const GraphSelectionPanel = _ref => { + let { + classes, + curveSt, + entityFileNames, + subLayoutsInfo, + layoutSt, + selectCurveAct, + toggleShowAllCurveAct + } = _ref; + let subLayoutValues = []; + if (subLayoutsInfo) { + subLayoutValues = Object.keys(subLayoutsInfo); + } + const [selectedSubLayout, setSelectedSublayout] = (0, _react.useState)(subLayoutValues[0]); + (0, _react.useEffect)(() => { + setSelectedSublayout(subLayoutValues[0]); + }, subLayoutValues); + if (!curveSt) { + return /*#__PURE__*/(0, _jsxRuntime.jsx)("span", {}); + } + const { + curveIdx, + listCurves, + isShowAllCurve + } = curveSt; + if (!listCurves) { + return /*#__PURE__*/(0, _jsxRuntime.jsx)("span", {}); + } + const onChange = idx => { + selectCurveAct(idx); + }; + const onChangeTabSubLayout = (event, newValue) => { + setSelectedSublayout(newValue); + }; + const onChangeSwitch = event => { + toggleShowAllCurveAct(event.target.checked); + }; + let itemsSubLayout = []; + if (selectedSubLayout && subLayoutValues.length > 1) { + const subLayout = subLayoutsInfo[selectedSubLayout]; + try { + itemsSubLayout = subLayout.map((spectra, idx) => { + const spectraIdx = spectra.curveIdx; + const { + color + } = spectra; + let filename = ''; + if (entityFileNames && spectraIdx < entityFileNames.length) { + filename = entityFileNames[spectraIdx]; + } + return { + name: `${idx + 1}.`, + idx: spectraIdx, + color, + filename + }; + }); + } catch (e) { + console.log(e); //eslint-disable-line + } + } + const items = listCurves.map((spectra, idx) => { + const { + color + } = spectra; + let filename = ''; + if (entityFileNames && idx < entityFileNames.length) { + filename = entityFileNames[idx]; + } + return { + name: `${idx + 1}.`, + idx, + color, + filename + }; + }); + return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_material.Accordion, { + "data-testid": "GraphSelectionPanel", + disableGutters: true, + sx: { + '&.MuiAccordion-root.Mui-expanded': { + margin: 0 + }, + '&:before': { + display: 'none' + } + }, + children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_material.AccordionSummary, { + expandIcon: /*#__PURE__*/(0, _jsxRuntime.jsx)(_ExpandMore.default, {}), + className: (0, _classnames.default)(classes.panelSummary), + children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Typography, { + className: "txt-panel-header", + children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: (0, _classnames.default)(classes.txtBadge, 'txt-sv-panel-title'), + children: "Graph selection" + }) + }) + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Divider, {}), layoutSt === _list_layout.LIST_LAYOUT.AIF ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.FormControlLabel, { + control: /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Switch, { + checked: isShowAllCurve, + onChange: onChangeSwitch + }), + label: "Show all curves" + }) : null, subLayoutValues && subLayoutValues.length > 1 ? /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", { + children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Tabs, { + value: selectedSubLayout, + onChange: onChangeTabSubLayout, + children: subLayoutValues.map((subLayout, i) => { + let subLayoutName = ''; + switch (subLayout.toUpperCase()) { + case 'G/MOL': + subLayoutName = 'MWD'; + break; + case 'MILLILITERS': + subLayoutName = 'ELU'; + break; + case 'INTENSITY': + subLayoutName = 'Chromatogram'; + break; + case 'DEGREES CELSIUS': + subLayoutName = 'Temperature'; + break; + default: + break; + } + return /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Tab, { + value: subLayout, + label: subLayoutName + }, i); + }) + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.List, { + children: itemsSubLayout.map(item => /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.ListItem, { + onClick: () => onChange(item.idx), + className: (0, _classnames.default)(item.idx === curveIdx ? classes.curveSelected : classes.curveDefault) // eslint-disable-line + , + children: /*#__PURE__*/(0, _jsxRuntime.jsxs)("span", { + className: (0, _classnames.default)(classes.curve), + children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("i", { + children: item.name + }), /*#__PURE__*/(0, _jsxRuntime.jsxs)("span", { + style: { + float: 'right', + width: '95%' + }, + children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("hr", { + className: (0, _classnames.default)(classes.line), + style: { + backgroundColor: item.color + } + }), item.filename !== '' ? /*#__PURE__*/(0, _jsxRuntime.jsxs)("span", { + children: ["File: ", item.filename] + }) : null // eslint-disable-line + ] + })] + }) + }, item.idx)) + })] + }) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.List, { + children: items.map(item => /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.ListItem, { + onClick: () => onChange(item.idx), + className: (0, _classnames.default)(item.idx === curveIdx ? classes.curveSelected : classes.curveDefault) // eslint-disable-line + , + children: /*#__PURE__*/(0, _jsxRuntime.jsxs)("span", { + className: (0, _classnames.default)(classes.curve), + children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("i", { + children: item.name + }), /*#__PURE__*/(0, _jsxRuntime.jsxs)("span", { + style: { + float: 'right', + width: '95%' + }, + children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("hr", { + className: (0, _classnames.default)(classes.line), + style: { + backgroundColor: item.color + } + }), item.filename !== '' ? /*#__PURE__*/(0, _jsxRuntime.jsxs)("span", { + children: ["File: ", item.filename] + }) : null // eslint-disable-line + ] + })] + }) + }, item.idx)) + })] + }); +}; +const mapStateToProps = (state, props) => ( +// eslint-disable-line +{ + layoutSt: state.layout, + curveSt: state.curve +}); +const mapDispatchToProps = dispatch => (0, _redux.bindActionCreators)({ + selectCurveAct: _curve.selectCurve, + toggleShowAllCurveAct: _curve.toggleShowAllCurves +}, dispatch); +GraphSelectionPanel.propTypes = { + classes: _propTypes.default.object.isRequired, + expand: _propTypes.default.bool.isRequired, + layoutSt: _propTypes.default.string.isRequired, + onExapnd: _propTypes.default.func.isRequired, + curveSt: _propTypes.default.object.isRequired, + selectCurveAct: _propTypes.default.func.isRequired, + entityFileNames: _propTypes.default.array.isRequired, + subLayoutsInfo: _propTypes.default.array, + toggleShowAllCurveAct: _propTypes.default.func.isRequired +}; +var _default = exports.default = (0, _reactRedux.connect)(mapStateToProps, mapDispatchToProps)((0, _styles.withStyles)(styles)(GraphSelectionPanel)); \ No newline at end of file diff --git a/dist/components/panel/index.js b/dist/components/panel/index.js new file mode 100644 index 00000000..03e803b0 --- /dev/null +++ b/dist/components/panel/index.js @@ -0,0 +1,170 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; +var _react = _interopRequireDefault(require("react")); +var _propTypes = _interopRequireDefault(require("prop-types")); +var _classnames = _interopRequireDefault(require("classnames")); +var _reactRedux = require("react-redux"); +var _redux = require("redux"); +var _styles = require("@mui/material/styles"); +var _withStyles = _interopRequireDefault(require("@mui/styles/withStyles")); +var _info = _interopRequireDefault(require("./info")); +var _peaks = _interopRequireDefault(require("./peaks")); +var _compare = _interopRequireDefault(require("./compare")); +var _multiplicity = _interopRequireDefault(require("./multiplicity")); +var _cyclic_voltamery_data = _interopRequireDefault(require("./cyclic_voltamery_data")); +var _graph_selection = _interopRequireDefault(require("./graph_selection")); +var _cfg = _interopRequireDefault(require("../../helpers/cfg")); +var _jsxRuntime = require("react/jsx-runtime"); +/* eslint-disable react/prop-types, react/require-default-props */ + +const theme = (0, _styles.createTheme)({ + typography: { + useNextVariants: true + }, + palette: { + background: { + default: '#D3D3D3' + } + } +}); +const styles = () => ({ + panels: { + maxHeight: 'calc(90vh - 220px)', + // ROI + display: 'table', + overflowX: 'hidden', + overflowY: 'auto', + margin: '5px 0 0 0', + padding: '0 0 0 0', + width: '100%' + } +}); +class PanelViewer extends _react.default.Component { + constructor(props) { + super(props); + this.state = { + expand: 'info' + }; + this.onExapnd = this.onExapnd.bind(this); + this.handleDescriptionChanged = this.handleDescriptionChanged.bind(this); + } + handleDescriptionChanged(content, delta, source, editor) { + if (source === 'user') { + const contentChanged = editor.getContents(); + this.props.onDescriptionChanged(contentChanged); // eslint-disable-line + } + } + onExapnd(input) { + const { + expand + } = this.state; + const nextExpand = input === expand ? '' : input; + this.setState({ + expand: nextExpand + }); + } + render() { + const { + expand + } = this.state; + const { + classes, + feature, + integration, + editorOnly, + molSvg, + descriptions, + layoutSt, + canChangeDescription, + jcampIdx, + entityFileNames, + curveSt, + userManualLink, + subLayoutsInfo, + exactMass + } = this.props; + const onExapndInfo = () => this.onExapnd('info'); + const onExapndPeak = () => this.onExapnd('peak'); + const onExapndMpy = () => this.onExapnd('mpy'); + const onExapndCompare = () => this.onExapnd('compare'); + const onExapndCyclicVolta = () => this.onExapnd('cyclicvolta'); + const onExapndGraphSelection = () => this.onExapnd('graph'); + const { + listCurves + } = curveSt; + const hideGraphSelection = listCurves === false || listCurves === undefined; + return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", { + className: (0, _classnames.default)(classes.panels), + children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_styles.StyledEngineProvider, { + injectFirst: true, + children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_styles.ThemeProvider, { + theme: theme, + children: [hideGraphSelection ? null : /*#__PURE__*/(0, _jsxRuntime.jsx)(_graph_selection.default, { + jcampIdx: jcampIdx, + entityFileNames: entityFileNames, + expand: expand === 'graph', + onExapnd: onExapndGraphSelection, + subLayoutsInfo: subLayoutsInfo + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_info.default, { + feature: feature, + integration: integration, + editorOnly: editorOnly, + expand: expand === 'info', + molSvg: molSvg, + exactMass: exactMass, + onExapnd: onExapndInfo, + descriptions: descriptions, + canChangeDescription: canChangeDescription, + onDescriptionChanged: this.handleDescriptionChanged + }), _cfg.default.hidePanelPeak(layoutSt) ? null : /*#__PURE__*/(0, _jsxRuntime.jsx)(_peaks.default, { + expand: expand === 'peak', + onExapnd: onExapndPeak + }), _cfg.default.hidePanelMpy(layoutSt) ? null : /*#__PURE__*/(0, _jsxRuntime.jsx)(_multiplicity.default, { + expand: expand === 'mpy', + onExapnd: onExapndMpy + }), _cfg.default.hidePanelCompare(layoutSt) || listCurves.length > 1 ? null : /*#__PURE__*/(0, _jsxRuntime.jsx)(_compare.default, { + expand: expand === 'compare', + onExapnd: onExapndCompare + }), _cfg.default.hidePanelCyclicVolta(layoutSt) ? null : /*#__PURE__*/(0, _jsxRuntime.jsx)(_cyclic_voltamery_data.default, { + jcampIdx: jcampIdx, + feature: feature, + expand: expand === 'cyclicvolta', + onExapnd: onExapndCyclicVolta, + userManualLink: userManualLink ? userManualLink.cv : undefined + })] + }) + }) + }); + } +} +const mapStateToProps = (state, _) => ( +// eslint-disable-line +{ + layoutSt: state.layout, + curveSt: state.curve +}); +const mapDispatchToProps = dispatch => (0, _redux.bindActionCreators)({}, dispatch); +PanelViewer.propTypes = { + classes: _propTypes.default.object.isRequired, + feature: _propTypes.default.object.isRequired, + integration: _propTypes.default.object.isRequired, + editorOnly: _propTypes.default.bool.isRequired, + molSvg: _propTypes.default.string.isRequired, + descriptions: _propTypes.default.array.isRequired, + layoutSt: _propTypes.default.string.isRequired, + canChangeDescription: _propTypes.default.bool.isRequired, + onDescriptionChanged: _propTypes.default.func, + entityFileNames: _propTypes.default.array, + userManualLink: _propTypes.default.object, + curveSt: _propTypes.default.object.isRequired, + subLayoutsInfo: _propTypes.default.object, + exactMass: _propTypes.default.string +}; +var _default = exports.default = (0, _reactRedux.connect)( +// eslint-disable-line +mapStateToProps, mapDispatchToProps)((0, _withStyles.default)(styles)(PanelViewer)); // eslint-disable-line \ No newline at end of file diff --git a/dist/components/panel/info.js b/dist/components/panel/info.js new file mode 100644 index 00000000..442f5d05 --- /dev/null +++ b/dist/components/panel/info.js @@ -0,0 +1,494 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; +var _react = _interopRequireDefault(require("react")); +var _propTypes = _interopRequireDefault(require("prop-types")); +var _classnames = _interopRequireDefault(require("classnames")); +var _reactRedux = require("react-redux"); +var _redux = require("redux"); +var _reactSvgFileZoomPan = _interopRequireDefault(require("@complat/react-svg-file-zoom-pan")); +var _reactQuill = _interopRequireDefault(require("react-quill")); +var _material = require("@mui/material"); +var _ExpandMore = _interopRequireDefault(require("@mui/icons-material/ExpandMore")); +var _styles = require("@mui/styles"); +var _format = _interopRequireDefault(require("../../helpers/format")); +var _meta = require("../../actions/meta"); +var _jsxRuntime = require("react/jsx-runtime"); +/* eslint-disable no-mixed-operators, react/function-component-definition, +react/require-default-props, max-len */ + +const styles = () => ({ + chip: { + margin: '1px 0 1px 0' + }, + panel: { + backgroundColor: '#eee', + display: 'table-row' + }, + panelSummary: { + backgroundColor: '#eee', + height: 32 + }, + subSectionHeader: { + backgroundColor: '#eee', + height: 32, + lineHeight: '32px', + paddingLeft: 10, + textAlign: 'left', + fontWeight: 'bold', + fontSize: '0.8rem', + fontFamily: 'Helvetica', + borderTop: '1px solid #dcdcdc', + color: 'rgba(0, 0, 0, 0.87)' + }, + panelDetail: { + backgroundColor: '#fff', + maxHeight: 'calc(90vh - 220px)', + // ROI + overflow: 'auto' + }, + table: { + width: 'auto' + }, + rowRoot: { + border: '1px solid #eee', + height: 36, + lineHeight: '36px', + overflow: 'hidden', + paddingLeft: 24, + textAlign: 'left' + }, + rowOdd: { + backgroundColor: '#fff', + textOverflow: 'ellipsis', + whiteSpace: 'nowrap' + }, + rowEven: { + backgroundColor: '#fafafa', + textOverflow: 'ellipsis', + whiteSpace: 'nowrap' + }, + rowOddSim: { + backgroundColor: '#fff', + height: 108, + lineHeight: '24px', + overflowY: 'hidden', + overflowWrap: 'word-break' + }, + tHead: { + fontWeight: 'bold', + float: 'left', + fontSize: '0.8rem', + fontFamily: 'Helvetica' + }, + tTxt: { + fontSize: '0.8rem', + fontFamily: 'Helvetica', + marginRight: 3 + }, + quill: { + fontSize: '0.8rem', + fontFamily: 'Helvetica', + textAlign: 'left' + }, + quillContainer: { + margin: '10px 10px', + backgroundColor: '#fff', + '& .ql-container': { + border: 'none' + }, + '& .ql-editor': { + minHeight: '60px' + }, + '& .ql-editor.ql-blank::before': { + fontStyle: 'normal', + color: 'rgba(0, 0, 0, 0.54)' + } + } +}); +const simTitle = () => 'Simulated signals from NMRshiftDB'; +const simContent = nmrSimPeaks => nmrSimPeaks && nmrSimPeaks.sort((a, b) => a - b).join(', '); +const normalizeQuillValue = val => { + if (!val) return ''; + if (val === '


' || val === '

') return ''; + return val; +}; +const handleDescriptionChanged = (value, onDescriptionChanged) => { + onDescriptionChanged(normalizeQuillValue(value)); +}; +const aucValue = integration => { + if (!integration) { + return ''; + } + const values = []; + const stackIntegration = integration.stack; + if (Array.isArray(stackIntegration)) { + let sumVal = 0.0; + stackIntegration.forEach(inte => { + if (inte.absoluteArea) { + sumVal += inte.absoluteArea; + } + }); + sumVal = sumVal.toFixed(2); + stackIntegration.forEach(inte => { + if (inte.absoluteArea) { + const areaVal = inte.absoluteArea.toFixed(2); + const percent = (areaVal * 100 / sumVal).toFixed(2); + const valStr = areaVal + " (" + percent + "%)"; // eslint-disable-line + values.push(valStr); + } + }); + } + return values.join(', '); +}; +const SECData = _ref => { + let { + classes, + layout, + detector, + secData + } = _ref; + if (_format.default.isSECLayout(layout) && secData) { + const { + d, + mn, + mp, + mw + } = secData; + return /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", { + children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)("div", { + className: (0, _classnames.default)(classes.rowRoot, classes.rowOdd), + children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: (0, _classnames.default)(classes.tTxt, classes.tHead, 'txt-sv-panel-txt'), + children: "Detector: " + }), /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: (0, _classnames.default)(classes.tTxt, 'txt-sv-panel-txt'), + children: detector + })] + }), /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", { + className: (0, _classnames.default)(classes.rowRoot, classes.rowEven), + children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: (0, _classnames.default)(classes.tTxt, classes.tHead, 'txt-sv-panel-txt'), + children: "D: " + }), /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: (0, _classnames.default)(classes.tTxt, 'txt-sv-panel-txt'), + children: d + })] + }), /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", { + className: (0, _classnames.default)(classes.rowRoot, classes.rowOdd), + children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: (0, _classnames.default)(classes.tTxt, classes.tHead, 'txt-sv-panel-txt'), + children: "MN: " + }), /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: (0, _classnames.default)(classes.tTxt, 'txt-sv-panel-txt'), + children: mn + })] + }), /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", { + className: (0, _classnames.default)(classes.rowRoot, classes.rowEven), + children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: (0, _classnames.default)(classes.tTxt, classes.tHead, 'txt-sv-panel-txt'), + children: "MP: " + }), /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: (0, _classnames.default)(classes.tTxt, 'txt-sv-panel-txt'), + children: mp + })] + }), /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", { + className: (0, _classnames.default)(classes.rowRoot, classes.rowOdd), + children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: (0, _classnames.default)(classes.tTxt, classes.tHead, 'txt-sv-panel-txt'), + children: "MW: " + }), /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: (0, _classnames.default)(classes.tTxt, 'txt-sv-panel-txt'), + children: mw + })] + })] + }); + } + return null; +}; +SECData.propTypes = { + classes: _propTypes.default.object.isRequired, + layout: _propTypes.default.string.isRequired, + detector: _propTypes.default.object.isRequired, + secData: _propTypes.default.object.isRequired +}; +const DSCData = _ref2 => { + let { + classes, + layout, + dscMetaData, + updateAction + } = _ref2; + if (_format.default.isDSCLayout(layout) && dscMetaData !== undefined) { + const { + meltingPoint, + tg + } = dscMetaData; + const onChange = e => { + const { + name, + value + } = e.target; + const dataToUpdate = { + meltingPoint, + tg + }; + dataToUpdate[name] = value; + updateAction(dataToUpdate); + }; + return /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", { + children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)("div", { + className: (0, _classnames.default)(classes.rowRoot, classes.rowOdd), + children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: (0, _classnames.default)(classes.tTxt, classes.tHead, 'txt-sv-panel-txt'), + children: "Melting Point: " + }), /*#__PURE__*/(0, _jsxRuntime.jsx)("input", { + type: "text", + name: "meltingPoint", + className: (0, _classnames.default)(classes.tTxt, 'txt-sv-panel-txt'), + value: meltingPoint, + onChange: onChange + })] + }), /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", { + className: (0, _classnames.default)(classes.rowRoot, classes.rowEven), + children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: (0, _classnames.default)(classes.tTxt, classes.tHead, 'txt-sv-panel-txt'), + children: "TG: " + }), /*#__PURE__*/(0, _jsxRuntime.jsx)("input", { + type: "text", + name: "tg", + className: (0, _classnames.default)(classes.tTxt, 'txt-sv-panel-txt'), + value: tg, + onChange: onChange + })] + })] + }); + } + return null; +}; +DSCData.propTypes = { + classes: _propTypes.default.object.isRequired, + layout: _propTypes.default.string.isRequired, + dscMetaData: _propTypes.default.object.isRequired, + updateAction: _propTypes.default.func.isRequired +}; +const InfoPanel = _ref3 => { + let { + classes, + expand, + feature, + integration, + editorOnly, + molSvg, + descriptions, + layoutSt, + simulationSt, + shiftSt, + curveSt, + exactMass, + onExapnd, + canChangeDescription, + onDescriptionChanged, + detectorSt, + metaSt, + updateDSCMetaDataAct + } = _ref3; + if (!feature) return null; + const { + title, + observeFrequency, + solventName, + secData + } = feature; + const { + dscMetaData + } = metaSt; + const { + curveIdx + } = curveSt; + const { + curves + } = detectorSt; + const getSelectedDetectorForCurve = (_detectorSt, targetCurveIdx) => { + const targetCurve = curves.find(curve => curve.curveIdx === targetCurveIdx); + return targetCurve ? targetCurve.selectedDetector.name : ''; + }; + let selectedDetector = getSelectedDetectorForCurve(detectorSt, curveIdx); + + // default detector from jcamp + if (!selectedDetector && feature.detector) { + selectedDetector = feature.detector; + } + const { + shifts + } = shiftSt; + const selectedShift = shifts[curveIdx]; + let showSolvName = solventName; + if (selectedShift !== undefined) { + const shiftName = selectedShift.ref.name; + showSolvName = shiftName === '- - -' ? solventName : shiftName; + } + let originStack = null; + if (integration) { + originStack = integration.originStack; // eslint-disable-line + } + return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_material.Accordion, { + "data-testid": "PanelInfo", + expanded: expand, + onChange: onExapnd, + disableGutters: true, + sx: { + '&.MuiAccordion-root.Mui-expanded': { + margin: 0 + }, + '&:before': { + display: 'none' + } + }, + TransitionProps: { + unmountOnExit: true + } // increase Accordion performance + , + children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_material.AccordionSummary, { + expandIcon: /*#__PURE__*/(0, _jsxRuntime.jsx)(_ExpandMore.default, {}), + className: (0, _classnames.default)(classes.panelSummary), + children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Typography, { + className: "txt-panel-header", + children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: (0, _classnames.default)(classes.txtBadge, 'txt-sv-panel-title'), + children: "Info" + }) + }) + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Divider, {}), /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", { + className: (0, _classnames.default)(classes.panelDetail), + children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)("div", { + className: (0, _classnames.default)(classes.rowRoot, classes.rowOdd), + children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: (0, _classnames.default)(classes.tTxt, classes.tHead, 'txt-sv-panel-txt'), + children: "Title : " + }), /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: (0, _classnames.default)(classes.tTxt, 'txt-sv-panel-txt'), + children: title + })] + }), _format.default.isNmrLayout(layoutSt) ? /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", { + className: (0, _classnames.default)(classes.rowRoot, classes.rowEven), + children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: (0, _classnames.default)(classes.tTxt, classes.tHead, 'txt-sv-panel-txt'), + children: "Freq : " + }), /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: (0, _classnames.default)(classes.tTxt, 'txt-sv-panel-txt'), + children: `${parseInt(observeFrequency, 10)} MHz` || ' - ' + })] + }) : null, _format.default.isNmrLayout(layoutSt) ? /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", { + className: (0, _classnames.default)(classes.rowRoot, classes.rowOdd), + children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: (0, _classnames.default)(classes.tTxt, classes.tHead, 'txt-sv-panel-txt'), + children: "Solv : " + }), /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: (0, _classnames.default)(classes.tTxt, 'txt-sv-panel-txt'), + children: showSolvName + })] + }) : null, _format.default.isMsLayout(layoutSt) && exactMass ? /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", { + className: (0, _classnames.default)(classes.rowRoot, classes.rowOdd), + children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: (0, _classnames.default)(classes.tTxt, classes.tHead, 'txt-sv-panel-txt'), + children: "Exact mass: " + }), /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: (0, _classnames.default)(classes.tTxt, 'txt-sv-panel-txt'), + children: `${parseFloat(exactMass).toFixed(6)} g/mol` + })] + }) : null, /*#__PURE__*/(0, _jsxRuntime.jsx)(SECData, { + classes: classes, + layout: layoutSt, + detector: selectedDetector, + secData: secData + }), !molSvg ? null : /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactSvgFileZoomPan.default, { + svg: molSvg, + duration: 300, + resize: true + }), _format.default.isHplcUvVisLayout(layoutSt) ? /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", { + className: (0, _classnames.default)(classes.rowRoot, classes.rowOddSim), + children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: (0, _classnames.default)(classes.tTxt, classes.tHead, 'txt-sv-panel-txt'), + children: "Area under curve (AUC):" + }), /*#__PURE__*/(0, _jsxRuntime.jsx)("br", {}), /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: (0, _classnames.default)(classes.tTxt, classes.tTxtSim, 'txt-sv-panel-txt'), + children: aucValue(integration) + })] + }) : null, /*#__PURE__*/(0, _jsxRuntime.jsx)(DSCData, { + classes: classes, + layout: layoutSt, + dscMetaData: dscMetaData, + updateAction: updateDSCMetaDataAct + }), !editorOnly && _format.default.isNmrLayout(layoutSt) ? /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, { + children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("div", { + className: classes.subSectionHeader, + children: simTitle() + }), /*#__PURE__*/(0, _jsxRuntime.jsx)("div", { + className: (0, _classnames.default)(classes.rowRoot, classes.rowOddSim), + children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: (0, _classnames.default)(classes.tTxt, classes.tTxtSim, 'txt-sv-panel-txt'), + children: simContent(simulationSt.nmrSimPeaks) + }) + })] + }) : null, !_format.default.isCyclicVoltaLayout(layoutSt) ? /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, { + children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("div", { + className: classes.subSectionHeader, + children: "Content" + }), /*#__PURE__*/(0, _jsxRuntime.jsx)("div", { + className: classes.quillContainer, + children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactQuill.default, { + className: (0, _classnames.default)(classes.quill, 'card-sv-quill'), + value: normalizeQuillValue(descriptions), + placeholder: canChangeDescription ? 'Peaks will be written here...' : undefined, + readOnly: true, + modules: { + toolbar: false + }, + onChange: value => handleDescriptionChanged(value, onDescriptionChanged) + }) + })] + }) : null] + })] + }); +}; +const mapStateToProps = (state, props) => ( +// eslint-disable-line +{ + layoutSt: state.layout, + simulationSt: state.simulation, + shiftSt: state.shift, + curveSt: state.curve, + detectorSt: state.detector, + metaSt: state.meta +}); +const mapDispatchToProps = dispatch => (0, _redux.bindActionCreators)({ + updateDSCMetaDataAct: _meta.updateDSCMetaData +}, dispatch); +InfoPanel.propTypes = { + classes: _propTypes.default.object.isRequired, + expand: _propTypes.default.bool.isRequired, + feature: _propTypes.default.object.isRequired, + integration: _propTypes.default.object.isRequired, + editorOnly: _propTypes.default.bool.isRequired, + molSvg: _propTypes.default.string.isRequired, + descriptions: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.array]).isRequired, + layoutSt: _propTypes.default.string.isRequired, + simulationSt: _propTypes.default.array.isRequired, + shiftSt: _propTypes.default.object.isRequired, + curveSt: _propTypes.default.object.isRequired, + onExapnd: _propTypes.default.func.isRequired, + canChangeDescription: _propTypes.default.bool.isRequired, + onDescriptionChanged: _propTypes.default.func, + exactMass: _propTypes.default.string, + detectorSt: _propTypes.default.object.isRequired, + metaSt: _propTypes.default.object.isRequired, + updateDSCMetaDataAct: _propTypes.default.func.isRequired +}; +var _default = exports.default = (0, _reactRedux.connect)( +// eslint-disable-line +mapStateToProps, mapDispatchToProps)((0, _styles.withStyles)(styles)(InfoPanel)); // eslint-disable-line \ No newline at end of file diff --git a/dist/components/panel/multiplicity.js b/dist/components/panel/multiplicity.js new file mode 100644 index 00000000..e522521a --- /dev/null +++ b/dist/components/panel/multiplicity.js @@ -0,0 +1,312 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; +var _react = _interopRequireDefault(require("react")); +var _propTypes = _interopRequireDefault(require("prop-types")); +var _classnames = _interopRequireDefault(require("classnames")); +var _reactRedux = require("react-redux"); +var _redux = require("redux"); +var _material = require("@mui/material"); +var _ExpandMore = _interopRequireDefault(require("@mui/icons-material/ExpandMore")); +var _HighlightOff = _interopRequireDefault(require("@mui/icons-material/HighlightOff")); +var _styles = require("@mui/styles"); +var _RefreshOutlined = _interopRequireDefault(require("@mui/icons-material/RefreshOutlined")); +var _multiplicity = require("../../actions/multiplicity"); +var _multiplicity_select = _interopRequireDefault(require("./multiplicity_select")); +var _multiplicity_coupling = _interopRequireDefault(require("./multiplicity_coupling")); +var _multiplicity_calc = require("../../helpers/multiplicity_calc"); +var _jsxRuntime = require("react/jsx-runtime"); +/* eslint-disable function-paren-newline, +function-call-argument-newline, react/function-component-definition */ + +const styles = theme => ({ + panel: { + backgroundColor: '#eee', + display: 'table-row' + }, + panelSummary: { + backgroundColor: '#eee', + height: 32 + }, + txtBadge: {}, + panelDetail: { + backgroundColor: '#fff', + maxHeight: 'calc(90vh - 220px)', + // ROI + overflow: 'auto' + }, + table: { + width: '100%' + }, + tRowHeadPos: { + backgroundColor: '#2196f3', + height: 32 + }, + tRowHeadNeg: { + backgroundColor: '#fa004f', + height: 32 + }, + tTxtHead: { + color: 'white', + padding: '4px 0 4px 5px' + }, + tTxtHeadXY: { + color: 'white', + padding: '4px 0 4px 90px' + }, + tTxt: { + padding: 0 + }, + tRow: { + height: 28, + '&:nth-of-type(even)': { + backgroundColor: theme.palette ? theme.palette.background.default : '#d3d3d3' + } + }, + rmBtn: { + color: 'red', + '&:hover': { + borderRadius: 12, + backgroundColor: 'red', + color: 'white' + } + }, + moCard: { + textAlign: 'left' + }, + moCardHead: { + backgroundColor: '#999', + color: 'white' + }, + moExtId: { + border: '2px solid white', + borderRadius: 12, + color: 'white', + margin: '0 5px 0 5px', + padding: '0 5px 0 5px' + }, + moExtTxt: { + margin: '0 5px 0 5x', + fontSize: '0.8rem', + fontFamily: 'Helvetica' + }, + moSelect: { + margin: '0 5x 0 5px', + fontSize: '0.8rem', + fontFamily: 'Helvetica' + }, + moCBox: { + marginLeft: 24, + padding: '4px 0 4px 4px' + }, + btnRf: { + color: '#fff', + float: 'right', + minWidth: 40, + right: 15 + } +}); +const cBoxStyle = () => ({ + root: { + color: 'white', + '&$checked': { + color: 'white' + } + }, + checked: {} +}); +const MUCheckbox = (0, _styles.withStyles)(cBoxStyle)(_material.Checkbox); +const createData = (idx, xExtent, peaks, shift, smExtext, mpyType, js, onClick, onRefresh) => ({ + idx: idx + 1, + xExtent, + onClick, + onRefresh, + peaks, + center: (0, _multiplicity_calc.calcMpyCenter)(peaks, shift, mpyType), + jStr: (0, _multiplicity_calc.calcMpyJStr)(js), + mpyType, + isCheck: smExtext.xL === xExtent.xL && smExtext.xU === xExtent.xU +}); +const pkList = (classes, row, shift, digits, rmMpyPeakByPanelAct) => row.peaks.map(pk => { + const { + xExtent + } = row; + const cb = () => rmMpyPeakByPanelAct({ + peak: pk, + xExtent + }); + const rmBtn = /*#__PURE__*/(0, _jsxRuntime.jsx)(_HighlightOff.default, { + onClick: cb, + className: classes.rmBtn + }); + return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_material.TableRow, { + className: classes.tRow, + hover: true, + children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_material.TableCell, { + align: "right", + className: (0, _classnames.default)(classes.tTxt, 'txt-sv-panel-txt'), + children: `(${(pk.x - shift).toFixed(digits)}, ${pk.y.toExponential(2)})` + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.TableCell, { + align: "right", + className: (0, _classnames.default)(classes.tTxt, 'txt-sv-panel-txt'), + children: rmBtn + })] + }, pk.x); +}); +const refreshBtn = (classes, onRefresh) => /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Tooltip, { + placement: "left", + title: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: "txt-sv-tp", + children: "Calculate Multiplicity" + }), + children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Button, { + className: classes.btnRf, + onClick: onRefresh, + children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_RefreshOutlined.default, {}) + }) +}); +const mpyList = (classes, digits, multiplicitySt, curveSt, clickMpyOneAct, rmMpyPeakByPanelAct, resetMpyOneAct) => { + const { + curveIdx + } = curveSt; + const { + multiplicities + } = multiplicitySt; + let selectedMulti = multiplicities[curveIdx]; + if (selectedMulti === undefined) { + selectedMulti = { + stack: [], + shift: 0, + smExtext: false, + edited: false + }; + } + const { + stack, + shift, + smExtext + } = selectedMulti; + const rows = stack.map((k, idx) => { + const { + peaks, + xExtent, + mpyType, + js + } = k; + const onRefresh = () => resetMpyOneAct(xExtent); + const onClick = e => { + e.stopPropagation(); + e.preventDefault(); + const payload = { + curveIdx, + payloadData: xExtent + }; + clickMpyOneAct(payload); + }; + return createData(idx, xExtent, peaks, shift, smExtext, mpyType, js, onClick, onRefresh); + }); + return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", { + children: rows.map(row => /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", { + className: classes.moCard, + children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)("div", { + className: classes.moCardHead, + children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)("div", { + children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(MUCheckbox, { + className: classes.moCBox, + checked: row.isCheck, + onChange: row.onClick + }), /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: (0, _classnames.default)(classes.moExtTxt, classes.moExtId, 'txt-sv-panel-head'), + children: row.idx + }), /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: (0, _classnames.default)(classes.moExtTxt, 'txt-sv-panel-head'), + children: `${row.center.toFixed(3)} (ppm)` + }), /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: (0, _classnames.default)(classes.moSelect, 'txt-sv-panel-head'), + children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_multiplicity_select.default, { + target: row + }) + }), refreshBtn(classes, row.onRefresh)] + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_multiplicity_coupling.default, { + row: row + })] + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Table, { + className: classes.table, + children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.TableBody, { + children: pkList(classes, row, shift, digits, rmMpyPeakByPanelAct) + }) + })] + }, row.idx)) + }); +}; +const MultiplicityPanel = _ref => { + let { + classes, + expand, + onExapnd, + multiplicitySt, + curveSt, + clickMpyOneAct, + rmMpyPeakByPanelAct, + resetMpyOneAct + } = _ref; + const digits = 4; + return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_material.Accordion, { + expanded: expand, + onChange: onExapnd, + disableGutters: true, + sx: { + '&.MuiAccordion-root.Mui-expanded': { + margin: 0 + }, + '&:before': { + display: 'none' + } + }, + TransitionProps: { + unmountOnExit: true + } // increase Accordion performance + , + children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_material.AccordionSummary, { + expandIcon: /*#__PURE__*/(0, _jsxRuntime.jsx)(_ExpandMore.default, {}), + className: (0, _classnames.default)(classes.panelSummary), + children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Typography, { + className: "txt-panel-header", + children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: (0, _classnames.default)(classes.txtBadge, 'txt-sv-panel-title'), + children: "Multiplicity" + }) + }) + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Divider, {}), /*#__PURE__*/(0, _jsxRuntime.jsx)("div", { + className: (0, _classnames.default)(classes.panelDetail), + children: mpyList(classes, digits, multiplicitySt, curveSt, clickMpyOneAct, rmMpyPeakByPanelAct, resetMpyOneAct) + })] + }); +}; +const mapStateToProps = (state, props) => ( +// eslint-disable-line +{ + integrationSt: state.integration.present, + multiplicitySt: state.multiplicity.present, + curveSt: state.curve +}); +const mapDispatchToProps = dispatch => (0, _redux.bindActionCreators)({ + clickMpyOneAct: _multiplicity.clickMpyOne, + rmMpyPeakByPanelAct: _multiplicity.rmMpyPeakByPanel, + resetMpyOneAct: _multiplicity.resetMpyOne +}, dispatch); +MultiplicityPanel.propTypes = { + classes: _propTypes.default.object.isRequired, + expand: _propTypes.default.bool.isRequired, + onExapnd: _propTypes.default.func.isRequired, + multiplicitySt: _propTypes.default.object.isRequired, + clickMpyOneAct: _propTypes.default.func.isRequired, + rmMpyPeakByPanelAct: _propTypes.default.func.isRequired, + resetMpyOneAct: _propTypes.default.func.isRequired, + curveSt: _propTypes.default.object.isRequired +}; +var _default = exports.default = (0, _reactRedux.connect)(mapStateToProps, mapDispatchToProps)((0, _styles.withStyles)(styles)(MultiplicityPanel)); \ No newline at end of file diff --git a/dist/components/panel/multiplicity_coupling.js b/dist/components/panel/multiplicity_coupling.js new file mode 100644 index 00000000..e245ceee --- /dev/null +++ b/dist/components/panel/multiplicity_coupling.js @@ -0,0 +1,139 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; +var _react = _interopRequireDefault(require("react")); +var _reactRedux = require("react-redux"); +var _redux = require("redux"); +var _classnames = _interopRequireDefault(require("classnames")); +var _propTypes = _interopRequireDefault(require("prop-types")); +var _styles = require("@mui/styles"); +var _material = require("@mui/material"); +var _multiplicity = require("../../actions/multiplicity"); +var _jsxRuntime = require("react/jsx-runtime"); +const styles = () => ({ + jDiv: { + height: 28 + }, + jTxt: { + margin: '0 5px 4px 60px' + }, + moExtTxt: { + margin: '0 5px 0 5x', + fontSize: '0.8rem', + fontFamily: 'Helvetica' + }, + txtField: { + width: 260, + margin: '0 3px 0 3px' + }, + txtInput: { + color: 'white', + fontSize: '0.9rem', + fontFamily: 'Helvetica', + height: 24 + } +}); +const txtJ = () => /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.InputAdornment, { + position: "start", + children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: "txt-cmd-j", + children: "J\xA0=" + }) +}); +const txtHz = () => /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.InputAdornment, { + position: "end", + children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: "txt-cmd-hz", + children: "Hz" + }) +}); +class MpyCoupling extends _react.default.Component { + constructor(props) { + super(props); + this.state = { + focus: false, + tmpVal: false + }; + this.onFocus = this.onFocus.bind(this); + this.onBlur = this.onBlur.bind(this); + this.onChange = this.onChange.bind(this); + } + onFocus() { + this.setState({ + focus: true + }); + } + onBlur() { + const { + row, + updateMpyJAct + } = this.props; + const { + tmpVal + } = this.state; + const { + xExtent + } = row; + this.setState({ + focus: false, + tmpVal: false + }); + updateMpyJAct({ + xExtent, + value: tmpVal + }); + } + onChange(e) { + this.setState({ + tmpVal: e.target.value + }); + } + render() { + const { + classes, + row + } = this.props; + const { + focus, + tmpVal + } = this.state; + const value = focus && (tmpVal || tmpVal === '') ? tmpVal : row.jStr; + return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", { + className: (0, _classnames.default)(classes.jDiv), + children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: (0, _classnames.default)(classes.moExtTxt, classes.jTxt, 'txt-sv-panel-head'), + children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.TextField, { + className: (0, _classnames.default)(classes.txtField, 'txt-cmd-field'), + placeholder: "-", + value: value, + margin: "none", + InputProps: { + startAdornment: txtJ(), + endAdornment: txtHz(), + className: (0, _classnames.default)(classes.txtInput, 'txt-sv-input-label') + }, + onChange: this.onChange, + onFocus: this.onFocus, + onBlur: this.onBlur, + variant: "outlined" + }) + }) + }); + } +} +const mapStateToProps = (state, props) => ( +// eslint-disable-line +{}); +const mapDispatchToProps = dispatch => (0, _redux.bindActionCreators)({ + updateMpyJAct: _multiplicity.updateMpyJ +}, dispatch); +MpyCoupling.propTypes = { + classes: _propTypes.default.object.isRequired, + row: _propTypes.default.object.isRequired, + updateMpyJAct: _propTypes.default.func.isRequired +}; +var _default = exports.default = (0, _reactRedux.connect)(mapStateToProps, mapDispatchToProps)((0, _styles.withStyles)(styles)(MpyCoupling)); \ No newline at end of file diff --git a/dist/components/panel/multiplicity_select.js b/dist/components/panel/multiplicity_select.js new file mode 100644 index 00000000..d56fb77f --- /dev/null +++ b/dist/components/panel/multiplicity_select.js @@ -0,0 +1,89 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; +var _react = _interopRequireDefault(require("react")); +var _propTypes = _interopRequireDefault(require("prop-types")); +var _classnames = _interopRequireDefault(require("classnames")); +var _reactRedux = require("react-redux"); +var _redux = require("redux"); +var _material = require("@mui/material"); +var _styles = require("@mui/styles"); +var _multiplicity = require("../../actions/multiplicity"); +var _jsxRuntime = require("react/jsx-runtime"); +/* eslint-disable react/function-component-definition */ + +const Styles = () => ({ + formControl: { + minWidth: 50, + margin: '2px 3px 0 3px' + }, + txtField: { + width: 120, + margin: '3px 3px 3px 3px' + }, + txtInput: { + height: 24, + fontSize: '0.9rem', + fontFamily: 'Helvetica', + color: 'white' + } +}); +const MpySelect = _ref => { + let { + classes, + target, + selectMpyTypeAct + } = _ref; + const { + mpyType, + xExtent + } = target; + const onBlur = e => selectMpyTypeAct({ + xExtent, + mpyType: e.target.value + }); + const onChange = e => selectMpyTypeAct({ + xExtent, + mpyType: e.target.value + }); + const onEnterPress = e => { + if (e.key === 'Enter') { + selectMpyTypeAct({ + xExtent, + mpyType: e.target.value + }); + } + }; + return /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.FormControl, { + className: (0, _classnames.default)(classes.formControl), + variant: "outlined", + children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.TextField, { + className: (0, _classnames.default)(classes.txtField, 'txt-cmd-field'), + value: mpyType, + margin: "none", + variant: "outlined", + InputProps: { + className: (0, _classnames.default)(classes.txtInput, 'txt-sv-input-label') + }, + onChange: onChange, + onBlur: onBlur, + onKeyPress: onEnterPress + }) + }); +}; +const mapStateToProps = (state, props) => ( +// eslint-disable-line +{}); +const mapDispatchToProps = dispatch => (0, _redux.bindActionCreators)({ + selectMpyTypeAct: _multiplicity.selectMpyType +}, dispatch); +MpySelect.propTypes = { + classes: _propTypes.default.object.isRequired, + target: _propTypes.default.object.isRequired, + selectMpyTypeAct: _propTypes.default.func.isRequired +}; +var _default = exports.default = (0, _reactRedux.connect)(mapStateToProps, mapDispatchToProps)((0, _styles.withStyles)(Styles)(MpySelect)); \ No newline at end of file diff --git a/dist/components/panel/peaks.js b/dist/components/panel/peaks.js new file mode 100644 index 00000000..7c0ba96d --- /dev/null +++ b/dist/components/panel/peaks.js @@ -0,0 +1,241 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; +var _react = _interopRequireDefault(require("react")); +var _propTypes = _interopRequireDefault(require("prop-types")); +var _classnames = _interopRequireDefault(require("classnames")); +var _reactRedux = require("react-redux"); +var _redux = require("redux"); +var _material = require("@mui/material"); +var _ExpandMore = _interopRequireDefault(require("@mui/icons-material/ExpandMore")); +var _HighlightOff = _interopRequireDefault(require("@mui/icons-material/HighlightOff")); +var _styles = require("@mui/styles"); +var _chem = require("../../helpers/chem"); +var _edit_peak = require("../../actions/edit_peak"); +var _format = _interopRequireDefault(require("../../helpers/format")); +var _jsxRuntime = require("react/jsx-runtime"); +/* eslint-disable react/function-component-definition, no-unused-vars */ + +const styles = theme => ({ + chip: { + margin: '1px 0 1px 0' + }, + panel: { + backgroundColor: '#eee', + display: 'table-row' + }, + panelSummary: { + backgroundColor: '#eee', + height: 32 + }, + txtBadge: {}, + panelDetail: { + backgroundColor: '#fff', + maxHeight: 'calc(90vh - 220px)', + // ROI + overflow: 'auto' + }, + table: { + width: '100%' + }, + tRowHeadPos: { + backgroundColor: '#999', + height: 32 + }, + tRowHeadNeg: { + backgroundColor: '#999', + height: 32 + }, + tTxtHead: { + color: 'white', + padding: '5px 5px 5px 5px' + }, + tTxtHeadXY: { + color: 'white', + padding: '4px 0 4px 90px' + }, + tTxt: { + padding: '4px 0 4px 0' + }, + tRow: { + height: 28, + '&:nth-of-type(even)': { + backgroundColor: theme.palette ? theme.palette.background.default : '#d3d3d3' + } + }, + rmBtn: { + color: 'red', + '&:hover': { + borderRadius: 12, + backgroundColor: 'red', + color: 'white' + } + } +}); +const createData = (classes, idx, x, y, cb, digits) => ({ + idx: idx + 1, + x: x.toFixed(digits), + y, + rmBtn: /*#__PURE__*/(0, _jsxRuntime.jsx)(_HighlightOff.default, { + onClick: cb, + className: classes.rmBtn + }) +}); +const peakList = (peaks, digits, cbAct, classes, isPos) => { + const rows = peaks.map((pp, idx) => { + const onDelete = () => cbAct(pp); + return createData(classes, idx, pp.x, pp.y, onDelete, digits); + }); + const rowKlass = isPos ? classes.tRowHeadPos : classes.tRowHeadNeg; + const headTxt = isPos ? 'P+' : 'P-'; + return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_material.Table, { + className: classes.table, + children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_material.TableHead, { + children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_material.TableRow, { + className: rowKlass, + children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_material.TableCell, { + align: "right", + className: (0, _classnames.default)(classes.tTxtHead, 'txt-sv-panel-head'), + children: /*#__PURE__*/(0, _jsxRuntime.jsx)("i", { + children: headTxt + }) + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.TableCell, { + align: "right", + className: (0, _classnames.default)(classes.tTxtHeadXY, 'txt-sv-panel-head'), + children: "X" + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.TableCell, { + align: "right", + className: (0, _classnames.default)(classes.tTxtHeadXY, 'txt-sv-panel-head'), + children: "Y" + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.TableCell, { + align: "right", + className: (0, _classnames.default)(classes.tTxtHead, 'txt-sv-panel-head'), + children: "-" + })] + }) + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.TableBody, { + children: rows.map(row => /*#__PURE__*/(0, _jsxRuntime.jsxs)(_material.TableRow, { + className: classes.tRow, + hover: true, + children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_material.TableCell, { + align: "right", + className: (0, _classnames.default)(classes.tTxt, 'txt-sv-panel-txt'), + children: row.idx + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.TableCell, { + align: "right", + className: (0, _classnames.default)(classes.tTxt, 'txt-sv-panel-txt'), + children: row.x + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.TableCell, { + align: "right", + className: (0, _classnames.default)(classes.tTxt, 'txt-sv-panel-txt'), + children: row.y.toExponential(2) + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.TableCell, { + align: "right", + className: (0, _classnames.default)(classes.tTxt, 'txt-sv-panel-txt'), + children: row.rmBtn + })] + }, row.idx)) + })] + }); +}; +const PeakPanel = _ref => { + let { + editPeakSt, + layoutSt, + classes, + expand, + onExapnd, + rmFromPosListAct, + rmFromNegListAct, + curveSt + } = _ref; + const { + curveIdx, + listCurves + } = curveSt; + const { + peaks + } = editPeakSt; + if (curveIdx >= peaks.length) { + return null; + } + const selectedEditPeaks = peaks[curveIdx]; + if (!selectedEditPeaks) { + return null; + } + const { + pos, + neg + } = selectedEditPeaks; + const selectedCurve = listCurves[curveIdx]; + if (!selectedCurve) { + return null; + } + const { + feature + } = selectedCurve; + const currentPeakOfCurve = (0, _chem.Convert2Peak)(feature); + const filteredArray = currentPeakOfCurve.filter(element => neg.includes(element)); + const peaksData = [].concat(filteredArray).concat(pos); + const digits = _format.default.isEmWaveLayout(layoutSt) ? 0 : 4; + return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_material.Accordion, { + "data-testid": "PeaksPanelInfo", + expanded: expand, + onChange: onExapnd, + disableGutters: true, + sx: { + '&.MuiAccordion-root.Mui-expanded': { + margin: 0 + }, + '&:before': { + display: 'none' + } + }, + TransitionProps: { + unmountOnExit: true + } // increase Accordion performance + , + children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_material.AccordionSummary, { + expandIcon: /*#__PURE__*/(0, _jsxRuntime.jsx)(_ExpandMore.default, {}), + className: (0, _classnames.default)(classes.panelSummary), + children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Typography, { + className: "txt-panel-header", + children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + className: (0, _classnames.default)(classes.txtBadge, 'txt-sv-panel-title'), + children: "Peaks" + }) + }) + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Divider, {}), /*#__PURE__*/(0, _jsxRuntime.jsx)("div", { + className: (0, _classnames.default)(classes.panelDetail), + children: peakList(peaksData, digits, rmFromPosListAct, classes, true) + })] + }); +}; +const mapStateToProps = (state, props) => ( +// eslint-disable-line +{ + editPeakSt: state.editPeak.present, + layoutSt: state.layout, + curveSt: state.curve +}); +const mapDispatchToProps = dispatch => (0, _redux.bindActionCreators)({ + rmFromPosListAct: _edit_peak.rmFromPosList, + rmFromNegListAct: _edit_peak.rmFromNegList +}, dispatch); +PeakPanel.propTypes = { + classes: _propTypes.default.object.isRequired, + expand: _propTypes.default.bool.isRequired, + editPeakSt: _propTypes.default.object.isRequired, + layoutSt: _propTypes.default.string.isRequired, + onExapnd: _propTypes.default.func.isRequired, + rmFromPosListAct: _propTypes.default.func.isRequired, + rmFromNegListAct: _propTypes.default.func.isRequired, + curveSt: _propTypes.default.object.isRequired +}; +var _default = exports.default = (0, _reactRedux.connect)( +// eslint-disable-line +mapStateToProps, mapDispatchToProps)((0, _styles.withStyles)(styles)(PeakPanel)); // eslint-disable-line \ No newline at end of file diff --git a/dist/constants/action_type.js b/dist/constants/action_type.js new file mode 100644 index 00000000..3647cbab --- /dev/null +++ b/dist/constants/action_type.js @@ -0,0 +1,150 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.XRD = exports.UI = exports.THRESHOLD = exports.SUBMIT = exports.STATUS = exports.SIMULATION = exports.SHIFT = exports.SEC = exports.SCAN = exports.MULTIPLICITY = exports.META = exports.MANAGER = exports.LAYOUT = exports.JCAMP = exports.INTEGRATION = exports.FORECAST = exports.EDITPEAK = exports.CYCLIC_VOLTA_METRY = exports.CURVE = exports.AXES = void 0; +const THRESHOLD = exports.THRESHOLD = { + UPDATE_VALUE: 'THRESHOLD_UPDATE_VALUE', + RESET_VALUE: 'THRESHOLD_RESET_VALUE', + TOGGLE_ISEDIT: 'THRESHOLD_TOGGLE_ISEDIT', + UPDATE_UPPER_VALUE: 'THRESHOLD_UPDATE_UPPER_VALUE', + UPDATE_LOWER_VALUE: 'THRESHOLD_UPDATE_LOWER_VALUE' +}; +const EDITPEAK = exports.EDITPEAK = { + ADD_POSITIVE: 'ADD_TO_POSITIVE_EDITPEAK_LIST', + ADD_NEGATIVE: 'ADD_TO_NEGATIVE_EDITPEAK_LIST', + RM_NEGATIVE: 'RM_FROM_NEGATIVE_EDITPEAK_LIST', + RM_POSITIVE: 'RM_FROM_POSITIVE_EDITPEAK_LIST', + SHIFT: 'EDITPEAK_SHIFT', + CLEAR_ALL: 'EDITPEAK_CLEAR_ALL' +}; +const STATUS = exports.STATUS = { + TOGGLEBTNSUBMIT: 'TOGGLE_BTN_SUBMIT', + TOGGLEBTNALL: 'TOGGLE_BTN_ALL', + ENABLEBTNALL: 'ENABLE_BTN_ALL' +}; +const MANAGER = exports.MANAGER = { + RESETALL: 'RESET_ALL', + RESETSHIFT: 'RESET_SHIFT', + RESET_INIT_COMMON: 'RESET_INIT_COMMON', + RESET_INIT_NMR: 'RESET_INIT_NMR', + RESET_INIT_MS: 'RESET_INIT_MS', + RESET_INIT_COMMON_WITH_INTERGATION: 'RESET_INIT_COMMON_WITH_INTERGATION', + RESET_DETECTOR: 'RESET_DETECTOR', + RESET_MULTIPLICITY: 'RESET_MULTIPLICITY' +}; +const LAYOUT = exports.LAYOUT = { + UPDATE: 'UPDATE_LAYOUT' +}; +const SHIFT = exports.SHIFT = { + SET_REF: 'SHIFT_SET_REF', + SET_PEAK: 'SHIFT_SET_PEAK', + RM_PEAK: 'SHIFT_RM_PEAK' +}; +const SCAN = exports.SCAN = { + SET_TARGET: 'SCAN_SET_TARGET', + RESET_TARGET: 'SCAN_RESET_TARGET', + TOGGLE_ISAUTO: 'SCAN_TOGGLE_ISAUTO' +}; +const UI = exports.UI = { + CLICK_TARGET: 'UI_CLICK_TARGET', + VIEWER: { + SET_TYPE: 'UI_VIEWER_SET_TYPE' + }, + SWEEP: { + SET_TYPE: 'UI_SWEEP_SET_TYPE', + SELECT: 'UI_SWEEP_SELECT', + SELECT_ZOOMIN: 'UI_SWEEP_SELECT_ZOOMIN', + SELECT_ZOOMRESET: 'UI_SWEEP_SELECT_ZOOMRESET', + SELECT_INTEGRATION: 'UI_SWEEP_SELECT_INTEGRATION', + SELECT_MULTIPLICITY: 'UI_SWEEP_SELECT_MULTIPLICITY', + SELECT_MULTIPLICITY_RDC: 'UI_SWEEP_SELECT_MULTIPLICITY_RDC' + }, + WHEEL: { + SCROLL: 'UI_WHEEL_SCROLL' + } +}; +const FORECAST = exports.FORECAST = { + INIT_STATUS: 'FORECAST_INIT_STATUS', + SET_IR_STATUS: 'FORECAST_SET_IR_STATUS', + SET_NMR_STATUS: 'FORECAST_SET_NMR_STATUS', + CLEAR_STATUS: 'FORECAST_CLEAR_STATUS' +}; +const SUBMIT = exports.SUBMIT = { + TOGGLE_IS_ASCEND: 'SUBMIT_TOGGLE_IS_ASCEND', + TOGGLE_IS_INTENSITY: 'SUBMIT_TOGGLE_IS_INTENSITY', + UPDATE_OPERATION: 'SUBMIT_UPDATE_OPERATION', + UPDATE_DECIMAL: 'SUBMIT_UPDATE_DECIMAL' +}; +const INTEGRATION = exports.INTEGRATION = { + RM_ONE: 'INTEGRATION_RM_ONE', + SET_REF: 'INTEGRATION_SET_REF', + SET_FKR: 'INTEGRATION_SET_FKR', + RESET_ALL_RDC: 'INTEGRATION_RESET_ALL_RDC', + CLEAR_ALL: 'INTEGRATION_CLEAR_ALL', + SWEEP: 'INTEGRATION_SWEEP' +}; +const SIMULATION = exports.SIMULATION = { + RESET_ALL_RDC: 'SIMULATION_RESET_ALL_RDC' +}; +const MULTIPLICITY = exports.MULTIPLICITY = { + ONE_CLICK: 'MULTIPLICITY_ONE_CLICK', + ONE_CLICK_BY_UI: 'MULTIPLICITY_ONE_CLICK_BY_UI', + PEAK_RM_BY_PANEL: 'MULTIPLICITY_PEAK_RM_BY_PANEL', + PEAK_RM_BY_PANEL_RDC: 'MULTIPLICITY_PEAK_RM_BY_PANEL_RDC', + PEAK_ADD_BY_UI_SAG: 'MULTIPLICITY_PEAK_ADD_BY_UI_SAG', + PEAK_ADD_BY_UI_RDC: 'MULTIPLICITY_PEAK_ADD_BY_UI_RDC', + PEAK_RM_BY_UI: 'MULTIPLICITY_PEAK_RM_BY_UI', + PEAK_RM_BY_UI_RDC: 'MULTIPLICITY_PEAK_RM_BY_UI_RDC', + TYPE_SELECT: 'MULTIPLICITY_TYPE_SELECT', + TYPE_SELECT_RDC: 'MULTIPLICITY_TYPE_SELECT_RDC', + RESET_ALL_RDC: 'MULTIPLICITY_RESET_ALL_RDC', + RESET_ONE: 'MULTIPLICITY_RESET_ONE', + RESET_ONE_RDC: 'MULTIPLICITY_RESET_ONE_RDC', + UPDATE_J: 'MULTIPLICITY_UPDATE_J', + CLEAR_ALL: 'MULTIPLICITY_CLEAR_ALL' +}; +const META = exports.META = { + UPDATE_PEAKS: 'META_UPDATE_PEAKS', + UPDATE_PEAKS_RDC: 'META_UPDATE_PEAKS_RDC', + UPDATE_META_DATA: 'UPDATE_META_DATA', + UPDATE_META_DATA_RDC: 'UPDATE_META_DATA_RDC' +}; +const JCAMP = exports.JCAMP = { + ADD_OTHERS: 'JCAMP_ADD_OTHERS', + RM_OTHERS_ONE: 'JCAMP_RM_OTHERS_ONE', + TOGGLE_SHOW: 'JCAMP_TOGGLE_SHOW', + CLEAR_ALL: 'JCAMP_CLEAR_ALL' +}; +const XRD = exports.XRD = { + UPDATE_WAVE_LENGTH: 'UPDATE_WAVE_LENGTH' +}; +const CYCLIC_VOLTA_METRY = exports.CYCLIC_VOLTA_METRY = { + ADD_PAIR_PEAKS: 'ADD_PAIR_PEAKS', + REMOVE_PAIR_PEAKS: 'REMOVE_PAIR_PEAKS', + ADD_MAX_PEAK: 'ADD_MAX_PEAK', + REMOVE_MAX_PEAK: 'REMOVE_MAX_PEAK', + ADD_MIN_PEAK: 'ADD_MIN_PEAK', + REMOVE_MIN_PEAK: 'REMOVE_MIN_PEAK', + SELECT_PAIR_PEAK: 'SELECT_PAIR_PEAK', + WORK_WITH_MAX_PEAK: 'WORK_WITH_MAX_PEAK', + ADD_PECKER: 'ADD_PECKER', + REMOVE_PECKER: 'REMOVE_PECKER', + RESETALL: 'RESETALL_VOLTA_METRY', + SET_REF: 'VOLTA_METRY_SET_REF', + SELECT_REF_PEAK: 'SELECT_REF_PEAK', + SET_FACTOR: 'CYCLIC_VOLTA_METRY_SET_FACTOR' +}; +const CURVE = exports.CURVE = { + SELECT_WORKING_CURVE: 'SELECT_WORKING_CURVE', + SET_ALL_CURVES: 'SET_ALL_CURVES', + SET_SHOULD_SHOW_ALL_CURVES: 'SET_SHOULD_SHOW_ALL_CURVES' +}; +const AXES = exports.AXES = { + UPDATE_X_AXIS: 'UPDATE_X_AXIS', + UPDATE_Y_AXIS: 'UPDATE_Y_AXIS' +}; +const SEC = exports.SEC = { + UPDATE_DETECTOR: 'UPDATE_DETECTOR' +}; \ No newline at end of file diff --git a/dist/constants/list_axes.js b/dist/constants/list_axes.js new file mode 100644 index 00000000..0936a991 --- /dev/null +++ b/dist/constants/list_axes.js @@ -0,0 +1,17 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.LIST_AXES = void 0; +var _list_layout = require("./list_layout"); +const optionsAxisX = { + [_list_layout.LIST_LAYOUT.CYCLIC_VOLTAMMETRY]: ['', 'Voltage in V', 'Voltage vs Ref in V', 'Potential in V', 'Potential vs Ref in V'] +}; +const optionsAxisY = { + [_list_layout.LIST_LAYOUT.CYCLIC_VOLTAMMETRY]: ['', 'Current in A', 'Current in mA'] +}; +const LIST_AXES = exports.LIST_AXES = { + x: optionsAxisX, + y: optionsAxisY +}; \ No newline at end of file diff --git a/dist/constants/list_detectors.js b/dist/constants/list_detectors.js new file mode 100644 index 00000000..fcbda7ec --- /dev/null +++ b/dist/constants/list_detectors.js @@ -0,0 +1,15 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.LIST_DETECTORS = void 0; +const rI = { + name: 'Refractive index', + label: 'RI' +}; +const uV = { + name: 'Ultraviolet', + label: 'UV' +}; +const LIST_DETECTORS = exports.LIST_DETECTORS = [rI, uV]; \ No newline at end of file diff --git a/dist/constants/list_layout.js b/dist/constants/list_layout.js new file mode 100644 index 00000000..cf5830ed --- /dev/null +++ b/dist/constants/list_layout.js @@ -0,0 +1,31 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.LIST_LAYOUT = void 0; +const LIST_LAYOUT = exports.LIST_LAYOUT = { + PLAIN: 'PLAIN', + IR: 'IR', + RAMAN: 'RAMAN', + UVVIS: 'UV/VIS', + H1: '1H', + C13: '13C', + F19: '19F', + P31: '31P', + N15: '15N', + Si29: '29Si', + MS: 'MS', + TGA: 'THERMOGRAVIMETRIC ANALYSIS', + XRD: 'X-RAY DIFFRACTION', + HPLC_UVVIS: 'HPLC UV/VIS', + CYCLIC_VOLTAMMETRY: 'CYCLIC VOLTAMMETRY', + CDS: 'CIRCULAR DICHROISM SPECTROSCOPY', + SEC: 'SIZE EXCLUSION CHROMATOGRAPHY', + AIF: 'AIF', + EMISSIONS: 'Emissions', + DLS_ACF: 'DLS ACF', + DLS_INTENSITY: 'DLS intensity', + DSC: 'DIFFERENTIAL SCANNING CALORIMETRY', + GC: 'GAS CHROMATOGRAPHY' +}; \ No newline at end of file diff --git a/dist/constants/list_shift.js b/dist/constants/list_shift.js new file mode 100644 index 00000000..63eaf99d --- /dev/null +++ b/dist/constants/list_shift.js @@ -0,0 +1,421 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.getListShift = exports.LIST_SHIFT_31P = exports.LIST_SHIFT_29Si = exports.LIST_SHIFT_1H = exports.LIST_SHIFT_19F = exports.LIST_SHIFT_15N = exports.LIST_SHIFT_13C = void 0; +var _list_layout = require("./list_layout"); +/* eslint-disable camelcase */ + +const noReference = { + name: '- - -', + value: 0.0, + label: false +}; +const cActicAcidD4Sept = { + name: 'Acetic acid-d4 (sept)', + value: 20.0, + label: 'Acetic acid-d4' +}; +const cActicAcidD4S = { + name: 'Acetic acid-d4 (s)', + value: 178.990, + label: 'Acetic acid-d4' +}; +const cAcetoneD6Sep = { + name: 'Acetone-d6 (sep)', + value: 29.640, + label: 'Acetone-d6', + nsdb: 'Acetone-D6 ((CD3)2CO)' +}; +const cAcetoneD6Broad = { + name: 'Acetone-d6 (broad)', + value: 206.260, + label: 'Acetone-d6', + nsdb: 'Acetone-D6 ((CD3)2CO)' +}; +const cAcetonitrileD3Sep = { + name: 'Acetonitrile-d3 (sep)', + value: 1.32, + label: 'Acetonitrile-d3', + nsdb: 'Acetonitrile-D3(CD3CN)' +}; +const cAcetonitrileD3S = { + name: 'Acetonitrile-d3 (s)', + value: 118.26, + label: 'Acetonitrile-d3', + nsdb: 'Acetonitrile-D3(CD3CN)' +}; +const cBenzeneT = { + name: 'Benzene (t)', + value: 128.060, + label: 'Benzene-d6', + nsdb: 'Benzene-D6 (C6D6)' +}; +const cChloroformDT = { + name: 'Chloroform-d (t)', + value: 77.16, + label: 'CDCl$3', + nsdb: 'Chloroform-D1 (CDCl3)' +}; +const cCyclohexaneD12Quin = { + name: 'Cyclohexane-d12 (quin)', + value: 26.430, + label: 'C$6D$1$2' +}; +const cDichloromethaneD2Quin = { + name: 'Dichloromethane-d2 (quin)', + value: 53.84, + label: 'CD$2Cl$2' +}; +const cDmfD7Sep1 = { + name: 'DMF-d7 (sep)-1', + value: 29.76, + label: 'DMF-d7' +}; +const cDmfD7Sep2 = { + name: 'DMF-d7 (sep)-2', + value: 34.89, + label: 'DMF-d7' +}; +const cDmfD7T3 = { + name: 'DMF-d7 (t)-3', + value: 163.15, + label: 'DMF-d7' +}; +const cDioxaneD8Quin = { + name: 'Dioxane-d8 (quin)', + value: 66.660, + label: 'Dioxane-d8' +}; +const cDmsoD6 = { + name: 'DMSO-d6', + value: 39.52, + label: 'DMSO-d6', + nsdb: 'Dimethylsulphoxide-D6 (DMSO-D6, C2D6SO)' +}; +const cEthanolD6Sep = { + name: 'Ethanol-d6 (sep)', + value: 17.3, + label: 'Ethanol-d6' +}; +const cEthanolD6Quin = { + name: 'Ethanol-d6 (quin)', + value: 56.96, + label: 'Ethanol-d6' +}; +const cMethanolD4Sep = { + name: 'Methanol-d4 (sep)', + value: 49.00, + label: 'Methanol-d4', + nsdb: 'Methanol-D4 (CD3OD)' +}; +const cPyridineD5T1 = { + name: 'Pyridine-d5 (t)-1', + value: 123.87, + label: 'Pyridine-d5', + nsdb: 'Pyridin-D5 (C5D5N)' +}; +const cPyridineD5T2 = { + name: 'Pyridine-d5 (t)-2', + value: 135.91, + label: 'Pyridine-d5', + nsdb: 'Pyridin-D5 (C5D5N)' +}; +const cPyridineD5T3 = { + name: 'Pyridine-d5 (t)-3', + value: 150.35, + label: 'Pyridine-d5', + nsdb: 'Pyridin-D5 (C5D5N)' +}; +const cThfD8Quin1 = { + name: 'THF-d8 (quin)-1', + value: 25.37, + label: 'THF-d8 ', + nsdb: 'Tetrahydrofuran-D8 (THF-D8, C4D4O)' +}; +const cThfD8Quin2 = { + name: 'THF-d8 (quin)-2', + value: 67.57, + label: 'THF-d8 ', + nsdb: 'Tetrahydrofuran-D8 (THF-D8, C4D4O)' +}; +const cTmsS = { + name: 'TMS (s)', + value: 0.00, + label: 'TMS' +}; +const cTolueneD8Sep1 = { + name: 'Toluene-d8 (sep)-1', + value: 20.4, + label: 'Toluene-d8' +}; +const cTolueneD8T2 = { + name: 'Toluene-d8 (t)-2', + value: 125.49, + label: 'Toluene-d8' +}; +const cTolueneD8T3 = { + name: 'Toluene-d8 (t)-3', + value: 128.33, + label: 'Toluene-d8' +}; +const cTolueneD8T4 = { + name: 'Toluene-d8 (t)-4', + value: 129.24, + label: 'Toluene-d8' +}; +const cTolueneD8T5 = { + name: 'Toluene-d8 (s)-5', + value: 137.86, + label: 'Toluene-d8' +}; +const cTfaDQ1 = { + name: 'TFA-d (q)-1', + value: 116.60, + label: 'TFA-d' +}; +const cTfaDQ2 = { + name: 'TFA-d (q)-2', + value: 164.20, + label: 'TFA-d' +}; +const cTrifluoroethanolD3Quin = { + name: 'Trifluoroethanol-d3 (quin)', + value: 61.80, + label: 'Trifluoroethanol-d3' +}; +const cTrifluoroethanolD3Broad = { + name: 'Trifluoroethanol-d3 (broad)', + value: 126.28, + label: 'Trifluoroethanol-d3' +}; +const cC6D5Cl1 = { + name: 'C6D5Cl (s)', + value: 134.19, + label: 'C6D5Cl' +}; +const cC6D5Cl2 = { + name: 'C6D5Cl (t)-1', + value: 129.26, + label: 'C6D5Cl' +}; +const cC6D5Cl3 = { + name: 'C6D5Cl (t)-2', + value: 128.25, + label: 'C6D5Cl' +}; +const cC6D5Cl4 = { + name: 'C6D5Cl (t)-3', + value: 125.96, + label: 'C6D5Cl' +}; +const LIST_SHIFT_13C = exports.LIST_SHIFT_13C = [noReference, cActicAcidD4Sept, cActicAcidD4S, cAcetoneD6Sep, cAcetoneD6Broad, cAcetonitrileD3Sep, cAcetonitrileD3S, cBenzeneT, cChloroformDT, cCyclohexaneD12Quin, cDichloromethaneD2Quin, cDmfD7Sep1, cDmfD7Sep2, cDmfD7T3, cDioxaneD8Quin, cDmsoD6, cEthanolD6Sep, cEthanolD6Quin, cMethanolD4Sep, cPyridineD5T1, cPyridineD5T2, cPyridineD5T3, cThfD8Quin1, cThfD8Quin2, cTmsS, cTolueneD8Sep1, cTolueneD8T2, cTolueneD8T3, cTolueneD8T4, cTolueneD8T5, cTfaDQ1, cTfaDQ2, cTrifluoroethanolD3Quin, cTrifluoroethanolD3Broad, cC6D5Cl1, cC6D5Cl2, cC6D5Cl3, cC6D5Cl4]; +const hActicAcidD4Quin = { + name: 'Acetic acid-d4 (quin)', + value: 2.04, + label: 'Acetic acid-d4' +}; +const hActicAcidD4S = { + name: 'Acetic acid-d4 (s)', + value: 11.65, + label: 'Acetic acid-d4' +}; +const hAcetoneD6Quin = { + name: 'Acetone-d6 (quin)', + value: 2.05, + label: 'Acetone-d6', + nsdb: 'Acetone-D6 ((CD3)2CO)' +}; +const hAcetonitrileD3Qquin = { + name: 'Acetonitrile-d3 (quin)', + value: 1.94, + label: 'Acetonitrile-d3', + nsdb: 'Acetonitrile-D3(CD3CN)' +}; +const hBenzeneS = { + name: 'Benzene (s)', + value: 7.16, + label: 'Benzene-d6', + nsdb: 'Benzene-D6 (C6D6)' +}; +const hChloroformDS = { + name: 'Chloroform-d (s)', + value: 7.26, + label: 'CDCl$3', + nsdb: 'Chloroform-D1 (CDCl3)' +}; +const hCyclohexaneD12S = { + name: 'Cyclohexane-d12 (s)', + value: 1.38, + label: 'C$6D$1$2' +}; +const hDeuteriumOxideS = { + name: 'D2O (s)', + value: 4.79, + label: 'D$2O', + nsdb: 'Deuteriumoxide (D2O)' +}; +const hDichloroethaneD4S = { + name: 'Dichloroethane-d4 (s)', + value: 3.72, + label: 'Dichloroethane-d4' +}; +const hDichloromethaneD2T = { + name: 'Dichloromethane-d2 (t)', + value: 5.32, + label: 'CD2Cl2', + nsdb: 'Methylenchloride-D2 (CD2Cl2)' +}; +const hDMFD7Quin1 = { + name: 'DMF-d7 (quin)-1', + value: 2.75, + label: 'DMF-d7' +}; +const hDMFD7Quin2 = { + name: 'DMF-d7 (quin)-2', + value: 2.92, + label: 'DMF-d7' +}; +const hDMFD7Broad3 = { + name: 'DMF-d7 (broad)-3', + value: 8.03, + label: 'DMF-d7' +}; +const hDioxaneD8Broad = { + name: 'Dioxane-d8 (broad)', + value: 3.53, + label: 'Dioxane-d8' +}; +const hDMSOD6Quin = { + name: 'DMSO-d6 (quin)', + value: 2.50, + label: 'DMSO-d6', + nsdb: 'Dimethylsulphoxide-D6 (DMSO-D6, C2D6SO)' +}; +const hEthanolD6Broad1 = { + name: 'Ethanol-d6 (broad)-1', + value: 1.11, + label: 'Ethanol-d6' +}; +const hEthanolD6S2 = { + name: 'Ethanol-d6 (s)-2', + value: 3.56, + label: 'Ethanol-d6' +}; +const hEthanolD6S3 = { + name: 'Ethanol-d6 (s)-3', + value: 5.29, + label: 'Ethanol-d6' +}; +const hMethanolD4Quin = { + name: 'Methanol-d4 (quin)', + value: 3.31, + label: 'Methanol-d4', + nsdb: 'Methanol-D4 (CD3OD)' +}; +const hMethanolD4S = { + name: 'Methanol-d4 (s)', + value: 4.87, + label: 'Methanol-d4', + nsdb: 'Methanol-D4 (CD3OD)' +}; +const hNitromethaneD3S = { + name: 'Nitromethane-d3 (s)', + value: 4.33, + label: 'Nitromethane-d3' +}; +const hPyridineD5Broad1 = { + name: 'Pyridine-d5 (broad)-1', + value: 7.22, + label: 'Pyridine-d5', + nsdb: 'Pyridin-D5 (C5D5N)' +}; +const hPyridineD5Broad2 = { + name: 'Pyridine-d5 (broad)-2', + value: 7.58, + label: 'Pyridine-d5', + nsdb: 'Pyridin-D5 (C5D5N)' +}; +const hPyridineD5Broad3 = { + name: 'Pyridine-d5 (broad)-3', + value: 8.74, + label: 'Pyridine-d5', + nsdb: 'Pyridin-D5 (C5D5N)' +}; +const hTHFD8S1 = { + name: 'THF-d8 (s)-1', + value: 1.73, + label: 'THF-d8', + nsdb: 'Tetrahydrofuran-D8 (THF-D8, C4D4O)' +}; +const hTHFD8S2 = { + name: 'THF-d8 (s)-2', + value: 3.58, + label: 'THF-d8', + nsdb: 'Tetrahydrofuran-D8 (THF-D8, C4D4O)' +}; +const hTMSS = { + name: 'TMS (s)', + value: 0.0, + label: 'TMS' +}; +const hTolueneD8Quin = { + name: 'Toluene-d8 (quin)-1', + value: 2.09, + label: 'Toluene-d8' +}; +const hTolueneD8Boad2 = { + name: 'Toluene-d8 (boad)-2', + value: 6.98, + label: 'Toluene-d8' +}; +const hTolueneD8S3 = { + name: 'Toluene-d8 (s)-3', + value: 7.00, + label: 'Toluene-d8' +}; +const hTolueneD8Broad4 = { + name: 'Toluene-d8 (broad)-4', + value: 7.09, + label: 'Toluene-d8' +}; +const hTFADS = { + name: 'TFA-d (s)', + value: 11.5, + label: 'TFA-d' +}; +const hTrifluoroethanolD31 = { + name: 'Trifluoroethanol-d3-1', + value: 3.88, + label: 'Trifluoroethanol-d3' +}; +const hTrifluoroethanolD32 = { + name: 'Trifluoroethanol-d3-2', + value: 5.02, + label: 'Trifluoroethanol-d3' +}; +const LIST_SHIFT_1H = exports.LIST_SHIFT_1H = [noReference, hActicAcidD4Quin, hActicAcidD4S, hAcetoneD6Quin, hAcetonitrileD3Qquin, hBenzeneS, hChloroformDS, hCyclohexaneD12S, hDeuteriumOxideS, hDichloroethaneD4S, hDichloromethaneD2T, hDMFD7Quin1, hDMFD7Quin2, hDMFD7Broad3, hDioxaneD8Broad, hDMSOD6Quin, hEthanolD6Broad1, hEthanolD6S2, hEthanolD6S3, hMethanolD4Quin, hMethanolD4S, hNitromethaneD3S, hPyridineD5Broad1, hPyridineD5Broad2, hPyridineD5Broad3, hTHFD8S1, hTHFD8S2, hTMSS, hTolueneD8Quin, hTolueneD8Boad2, hTolueneD8S3, hTolueneD8Broad4, hTFADS, hTrifluoroethanolD31, hTrifluoroethanolD32]; +const LIST_SHIFT_19F = exports.LIST_SHIFT_19F = [noReference, hActicAcidD4Quin, hActicAcidD4S, hAcetoneD6Quin, hAcetonitrileD3Qquin, hBenzeneS, hChloroformDS, hCyclohexaneD12S, hDeuteriumOxideS, hDichloroethaneD4S, hDichloromethaneD2T, hDMFD7Quin1, hDMFD7Quin2, hDMFD7Broad3, hDioxaneD8Broad, hDMSOD6Quin, hEthanolD6Broad1, hEthanolD6S2, hEthanolD6S3, hMethanolD4Quin, hMethanolD4S, hNitromethaneD3S, hPyridineD5Broad1, hPyridineD5Broad2, hPyridineD5Broad3, hTHFD8S1, hTHFD8S2, hTMSS, hTolueneD8Quin, hTolueneD8Boad2, hTolueneD8S3, hTolueneD8Broad4, hTFADS, hTrifluoroethanolD31, hTrifluoroethanolD32]; +const LIST_SHIFT_31P = exports.LIST_SHIFT_31P = [noReference, hActicAcidD4Quin, hActicAcidD4S, hAcetoneD6Quin, hAcetonitrileD3Qquin, hBenzeneS, hChloroformDS, hCyclohexaneD12S, hDeuteriumOxideS, hDichloroethaneD4S, hDichloromethaneD2T, hDMFD7Quin1, hDMFD7Quin2, hDMFD7Broad3, hDioxaneD8Broad, hDMSOD6Quin, hEthanolD6Broad1, hEthanolD6S2, hEthanolD6S3, hMethanolD4Quin, hMethanolD4S, hNitromethaneD3S, hPyridineD5Broad1, hPyridineD5Broad2, hPyridineD5Broad3, hTHFD8S1, hTHFD8S2, hTMSS, hTolueneD8Quin, hTolueneD8Boad2, hTolueneD8S3, hTolueneD8Broad4, hTFADS, hTrifluoroethanolD31, hTrifluoroethanolD32]; +const LIST_SHIFT_15N = exports.LIST_SHIFT_15N = [noReference, hActicAcidD4Quin, hActicAcidD4S, hAcetoneD6Quin, hAcetonitrileD3Qquin, hBenzeneS, hChloroformDS, hCyclohexaneD12S, hDeuteriumOxideS, hDichloroethaneD4S, hDichloromethaneD2T, hDMFD7Quin1, hDMFD7Quin2, hDMFD7Broad3, hDioxaneD8Broad, hDMSOD6Quin, hEthanolD6Broad1, hEthanolD6S2, hEthanolD6S3, hMethanolD4Quin, hMethanolD4S, hNitromethaneD3S, hPyridineD5Broad1, hPyridineD5Broad2, hPyridineD5Broad3, hTHFD8S1, hTHFD8S2, hTMSS, hTolueneD8Quin, hTolueneD8Boad2, hTolueneD8S3, hTolueneD8Broad4, hTFADS, hTrifluoroethanolD31, hTrifluoroethanolD32]; +const LIST_SHIFT_29Si = exports.LIST_SHIFT_29Si = [noReference, hActicAcidD4Quin, hActicAcidD4S, hAcetoneD6Quin, hAcetonitrileD3Qquin, hBenzeneS, hChloroformDS, hCyclohexaneD12S, hDeuteriumOxideS, hDichloroethaneD4S, hDichloromethaneD2T, hDMFD7Quin1, hDMFD7Quin2, hDMFD7Broad3, hDioxaneD8Broad, hDMSOD6Quin, hEthanolD6Broad1, hEthanolD6S2, hEthanolD6S3, hMethanolD4Quin, hMethanolD4S, hNitromethaneD3S, hPyridineD5Broad1, hPyridineD5Broad2, hPyridineD5Broad3, hTHFD8S1, hTHFD8S2, hTMSS, hTolueneD8Quin, hTolueneD8Boad2, hTolueneD8S3, hTolueneD8Broad4, hTFADS, hTrifluoroethanolD31, hTrifluoroethanolD32]; +const getListShift = layoutSt => { + switch (layoutSt) { + case _list_layout.LIST_LAYOUT.H1: + return LIST_SHIFT_1H; + case _list_layout.LIST_LAYOUT.C13: + return LIST_SHIFT_13C; + case _list_layout.LIST_LAYOUT.F19: + return LIST_SHIFT_19F; + case _list_layout.LIST_LAYOUT.P31: + return LIST_SHIFT_31P; + case _list_layout.LIST_LAYOUT.N15: + return LIST_SHIFT_15N; + case _list_layout.LIST_LAYOUT.Si29: + return LIST_SHIFT_29Si; + default: + return []; + } +}; +exports.getListShift = getListShift; \ No newline at end of file diff --git a/dist/constants/list_ui.js b/dist/constants/list_ui.js new file mode 100644 index 00000000..ad219334 --- /dev/null +++ b/dist/constants/list_ui.js @@ -0,0 +1,35 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.LIST_UI_VIEWER_TYPE = exports.LIST_UI_SWEEP_TYPE = exports.LIST_NON_BRUSH_TYPES = void 0; +const LIST_UI_VIEWER_TYPE = exports.LIST_UI_VIEWER_TYPE = { + SPECTRUM: 'spectrum', + ANALYSIS: 'analysis' +}; +const LIST_UI_SWEEP_TYPE = exports.LIST_UI_SWEEP_TYPE = { + ZOOMIN: 'zoom in', + ZOOMRESET: 'zoom reset', + INTEGRATION_ADD: 'integration add', + INTEGRATION_RM: 'integration remove', + INTEGRATION_REF: 'integration reference', + INTEGRATION_SET_REF: 'integration set ref', + MULTIPLICITY_SWEEP_ADD: 'multiplicity sweep add', + MULTIPLICITY_ONE_CLICK: 'multiplicity one click', + MULTIPLICITY_ONE_RM: 'multiplicity one remove', + MULTIPLICITY_PEAK_ADD: 'multiplicity peak add', + MULTIPLICITY_PEAK_RM: 'multiplicity peak remove', + MULTIPLICITY_ALL_CLEAR: 'multiplicity all clear', + PEAK_ADD: 'peak add', + PEAK_DELETE: 'peak delete', + ANCHOR_SHIFT: 'anchor shift', + CYCLIC_VOLTA_ADD_MAX_PEAK: 'cyclic voltammetry add max peak', + CYCLIC_VOLTA_RM_MAX_PEAK: 'cyclic voltammetry remove max peak', + CYCLIC_VOLTA_ADD_MIN_PEAK: 'cyclic voltammetry add min peak', + CYCLIC_VOLTA_RM_MIN_PEAK: 'cyclic voltammetry remove min peak', + CYCLIC_VOLTA_ADD_PECKER: 'cyclic voltammetry add pecker', + CYCLIC_VOLTA_RM_PECKER: 'cyclic voltammetry remove pecker', + CYCLIC_VOLTA_SET_REF: 'cyclic voltammetry set ref' +}; +const LIST_NON_BRUSH_TYPES = exports.LIST_NON_BRUSH_TYPES = [LIST_UI_SWEEP_TYPE.PEAK_ADD, LIST_UI_SWEEP_TYPE.PEAK_DELETE, LIST_UI_SWEEP_TYPE.ANCHOR_SHIFT, LIST_UI_SWEEP_TYPE.INTEGRATION_RM, LIST_UI_SWEEP_TYPE.INTEGRATION_SET_REF, LIST_UI_SWEEP_TYPE.MULTIPLICITY_PEAK_ADD, LIST_UI_SWEEP_TYPE.MULTIPLICITY_PEAK_RM, LIST_UI_SWEEP_TYPE.MULTIPLICITY_ONE_CLICK, LIST_UI_SWEEP_TYPE.MULTIPLICITY_ONE_RM, LIST_UI_SWEEP_TYPE.CYCLIC_VOLTA_ADD_MAX_PEAK, LIST_UI_SWEEP_TYPE.CYCLIC_VOLTA_RM_MAX_PEAK, LIST_UI_SWEEP_TYPE.CYCLIC_VOLTA_ADD_MIN_PEAK, LIST_UI_SWEEP_TYPE.CYCLIC_VOLTA_RM_MIN_PEAK, LIST_UI_SWEEP_TYPE.CYCLIC_VOLTA_ADD_PECKER, LIST_UI_SWEEP_TYPE.CYCLIC_VOLTA_RM_PECKER, LIST_UI_SWEEP_TYPE.CYCLIC_VOLTA_SET_REF]; \ No newline at end of file diff --git a/dist/constants/list_wavelength.js b/dist/constants/list_wavelength.js new file mode 100644 index 00000000..2643b05d --- /dev/null +++ b/dist/constants/list_wavelength.js @@ -0,0 +1,31 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.LIST_WAVE_LENGTH = void 0; +const CuKalpha = { + name: 'CuKalpha', + value: 0.15406, + label: 'Cu K\u03B1', + unit: 'nm' +}; +const Fe = { + name: 'Fe', + value: 0.19373, + label: 'Fe', + unit: 'nm' +}; +const Co = { + name: 'Co', + value: 0.17902, + label: 'Co', + unit: 'nm' +}; +const MoKalpha = { + name: 'MoKalpha', + value: 0.07107, + label: 'Mo K\u03B1', + unit: 'nm' +}; +const LIST_WAVE_LENGTH = exports.LIST_WAVE_LENGTH = [CuKalpha, Fe, Co, MoKalpha]; \ No newline at end of file diff --git a/dist/fn.js b/dist/fn.js new file mode 100644 index 00000000..348a8fe8 --- /dev/null +++ b/dist/fn.js @@ -0,0 +1,23 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; +var _format = _interopRequireDefault(require("./helpers/format")); +var _chem = require("./helpers/chem"); +var _converter = require("./helpers/converter"); +var _multiplicity_calc = require("./helpers/multiplicity_calc"); +var _carbonFeatures = require("./helpers/carbonFeatures"); +var _list_layout = require("./constants/list_layout"); +/* eslint-disable prefer-object-spread */ + +const FN = Object.assign({}, _format.default, { + ExtractJcamp: _chem.ExtractJcamp, + ToXY: _converter.ToXY, + LIST_LAYOUT: _list_layout.LIST_LAYOUT, + CalcMpyCenter: _multiplicity_calc.calcMpyCenter, + CarbonFeatures: _carbonFeatures.carbonFeatures +}); +var _default = exports.default = FN; \ No newline at end of file diff --git a/dist/helpers/brush.js b/dist/helpers/brush.js new file mode 100644 index 00000000..309f49d7 --- /dev/null +++ b/dist/helpers/brush.js @@ -0,0 +1,100 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; +var _compass = require("./compass"); +/* eslint-disable prefer-object-spread */ + +const d3 = require('d3'); +const wheeled = (focus, event) => { + const { + currentExtent, + scrollUiWheelAct + } = focus; + // WORKAROUND: firefox wheel compatibilty + const wheelEvent = focus.isFirefox ? -event.deltaY : event.wheelDelta; // eslint-disable-line + const direction = wheelEvent > 0; + scrollUiWheelAct(Object.assign({}, currentExtent, { + direction + })); +}; +const brushed = (focus, isUiAddIntgSt, event) => { + const { + selectUiSweepAct, + data, + dataPks, + brush, + w, + h, + scales + } = focus; + const selection = event.selection && event.selection.reverse(); + if (!selection) return; + let xes = [w, 0].map(scales.x.invert).sort((a, b) => a - b); + let yes = [h, 0].map(scales.y.invert).sort((a, b) => a - b); + let xExtent = { + xL: xes[0], + xU: xes[1] + }; + let yExtent = { + yL: yes[0], + yU: yes[1] + }; + if (isUiAddIntgSt) { + xes = selection.map(scales.x.invert).sort((a, b) => a - b); + xExtent = { + xL: xes[0], + xU: xes[1] + }; + } else { + const [begPt, endPt] = selection; + xes = [begPt[0], endPt[0]].map(scales.x.invert).sort((a, b) => a - b); + yes = [begPt[1], endPt[1]].map(scales.y.invert).sort((a, b) => a - b); + xExtent = { + xL: xes[0], + xU: xes[1] + }; + yExtent = { + yL: yes[0], + yU: yes[1] + }; + } + selectUiSweepAct({ + xExtent, + yExtent, + data, + dataPks + }); + d3.select('.d3Svg').selectAll('.brush').call(brush.move, null); +}; +const MountBrush = (focus, isUiAddIntgSt, isUiNoBrushSt) => { + const { + root, + svg, + brush, + brushX, + w, + h + } = focus; + svg.selectAll('.brush').remove(); + svg.selectAll('.brushX').remove(); + const brushedCb = event => brushed(focus, isUiAddIntgSt, event); + const wheeledCb = event => wheeled(focus, event); + if (isUiNoBrushSt) { + const target = isUiAddIntgSt ? brushX : brush; + target.handleSize(10).extent([[0, 0], [w, h]]).on('end', brushedCb); + + // append brush components + const klass = isUiAddIntgSt ? 'brushX' : 'brush'; + root.append('g').attr('class', klass).on('mousemove', event => (0, _compass.MouseMove)(event, focus)).call(target); + } + svg.on('wheel', wheeledCb); +}; +var _default = exports.default = MountBrush; // const resetedCb = () => reseted(main); +// main.svg.on('dblclick', resetedCb); +// const reseted = (main) => { +// const { selectUiSweepAct } = main; +// selectUiSweepAct({ xExtent: false, yExtent: false }); +// }; \ No newline at end of file diff --git a/dist/helpers/calc.js b/dist/helpers/calc.js new file mode 100644 index 00000000..664ffdf8 --- /dev/null +++ b/dist/helpers/calc.js @@ -0,0 +1,15 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.calcSlope = exports.almostEqual = void 0; +const almostEqual = (a, b) => Math.abs(a - b) < 0.00000001 * Math.abs(a + b); +exports.almostEqual = almostEqual; +const calcSlope = (x1, y1, x2, y2) => { + if (x2 === x1) { + return 0; + } + return (y2 - y1) / (x2 - x1); +}; +exports.calcSlope = calcSlope; \ No newline at end of file diff --git a/dist/helpers/carbonFeatures.js b/dist/helpers/carbonFeatures.js new file mode 100644 index 00000000..3c97f566 --- /dev/null +++ b/dist/helpers/carbonFeatures.js @@ -0,0 +1,51 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.carbonFeatures = void 0; +var _multiplicity_calc = require("./multiplicity_calc"); +const carbonFeatures = (peaksEdit, multiplicitySt) => { + const { + selectedIdx, + multiplicities + } = multiplicitySt; + const selectedMultiplicity = multiplicities[selectedIdx]; + const { + stack, + shift + } = selectedMultiplicity; + const nmrMpyCenters = stack.map(stk => { + // eslint-disable-line + return { + x: (0, _multiplicity_calc.calcMpyCenter)(stk.peaks, shift, stk.mpyType), + y: 0 + }; + }); + let targetIdxs = []; + stack.forEach(stk => { + // find peak idxs to be removed + stk.peaks.forEach(p => { + let targetIdx = -1; + let minDiff = 999999999; + peaksEdit.forEach((pe, idx) => { + const xDiff = Math.abs(pe.x - p.x); + if (xDiff < minDiff) { + targetIdx = idx; + minDiff = xDiff; + } + }); + targetIdxs = [...targetIdxs, targetIdx]; + }); + }); + let features = [...nmrMpyCenters]; + peaksEdit.forEach((pe, idx) => { + if (targetIdxs.indexOf(idx) < 0) { + features = [...features, pe]; + } + }); + return features; +}; + +// eslint-disable-line +exports.carbonFeatures = carbonFeatures; \ No newline at end of file diff --git a/dist/helpers/cfg.js b/dist/helpers/cfg.js new file mode 100644 index 00000000..e61695f4 --- /dev/null +++ b/dist/helpers/cfg.js @@ -0,0 +1,65 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; +var _format = _interopRequireDefault(require("./format")); +const btnCmdAnaViewer = layoutSt => _format.default.isMsLayout(layoutSt) || _format.default.isRamanLayout(layoutSt) || _format.default.is19FLayout(layoutSt) || _format.default.isUvVisLayout(layoutSt) || _format.default.isHplcUvVisLayout(layoutSt) || _format.default.isTGALayout(layoutSt) || _format.default.isDSCLayout(layoutSt) || _format.default.isXRDLayout(layoutSt) || _format.default.is31PLayout(layoutSt) || _format.default.is15NLayout(layoutSt) || _format.default.is29SiLayout(layoutSt) || _format.default.isCyclicVoltaLayout(layoutSt) || _format.default.isCDSLayout(layoutSt) || _format.default.isSECLayout(layoutSt) || _format.default.isGCLayout(layoutSt); +const hideCmdAnaViewer = () => false; +const btnCmdAddPeak = layoutSt => _format.default.isMsLayout(layoutSt); +const btnCmdRmPeak = layoutSt => _format.default.isMsLayout(layoutSt); +const btnCmdSetRef = layoutSt => !_format.default.isNmrLayout(layoutSt); // eslint-disable-line + +const btnCmdIntg = layoutSt => !(_format.default.isNmrLayout(layoutSt) || _format.default.isHplcUvVisLayout(layoutSt)); // eslint-disable-line + +const btnCmdMpy = layoutSt => !_format.default.isNmrLayout(layoutSt); +const btnCmdMpyPeak = function btnCmdMpyPeak(layoutSt, mpySt) { + let curveIdx = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0; + const { + multiplicities + } = mpySt; + let smExtextVal = false; + if (multiplicities) { + const selectedMultiplicity = multiplicities[curveIdx]; + if (selectedMultiplicity) { + const { + smExtext + } = selectedMultiplicity; + smExtextVal = smExtext; + } + } + return btnCmdMpy(layoutSt) || !smExtextVal; +}; +const hideCmdThres = layoutSt => _format.default.isMsLayout(layoutSt); +const btnCmdThres = thresVal => !thresVal; + +// const hidePanelPeak = layoutSt => Format.isMsLayout(layoutSt); +const hidePanelPeak = layoutSt => !_format.default.isSECLayout(layoutSt); // eslint-disable-line + +const hidePanelMpy = layoutSt => !_format.default.isNmrLayout(layoutSt); +const hidePanelCompare = layoutSt => !(_format.default.isIrLayout(layoutSt) || _format.default.isHplcUvVisLayout(layoutSt) || _format.default.isXRDLayout(layoutSt)); // eslint-disable-line + +const hideSolvent = layoutSt => !_format.default.isNmrLayout(layoutSt); +const showTwoThreshold = layoutSt => _format.default.isCyclicVoltaLayout(layoutSt); +const hidePanelCyclicVolta = layoutSt => !_format.default.isCyclicVoltaLayout(layoutSt); +const Config = { + btnCmdAnaViewer, + hideCmdAnaViewer, + btnCmdAddPeak, + btnCmdRmPeak, + btnCmdSetRef, + btnCmdIntg, + btnCmdMpy, + btnCmdMpyPeak, + hideCmdThres, + btnCmdThres, + hidePanelPeak, + hidePanelMpy, + hidePanelCompare, + hideSolvent, + showTwoThreshold, + hidePanelCyclicVolta +}; +var _default = exports.default = Config; \ No newline at end of file diff --git a/dist/helpers/chem.js b/dist/helpers/chem.js new file mode 100644 index 00000000..e4a2640a --- /dev/null +++ b/dist/helpers/chem.js @@ -0,0 +1,937 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.convertTopic = exports.Topic2Seed = exports.ToThresEndPts = exports.ToShiftPeaks = exports.ToFrequency = exports.GetCyclicVoltaShiftOffset = exports.GetCyclicVoltaRatio = exports.GetCyclicVoltaPreviousShift = exports.GetCyclicVoltaPeakSeparate = exports.GetComparisons = exports.Feature2Peak = exports.Feature2MaxMinPeak = exports.ExtractJcamp = exports.Convert2Thres = exports.Convert2Scan = exports.Convert2Peak = exports.Convert2MaxMinPeak = exports.Convert2DValue = void 0; +var _jcampconverter = _interopRequireDefault(require("jcampconverter")); +var _reselect = require("reselect"); +var _shift = require("./shift"); +var _cfg = _interopRequireDefault(require("./cfg")); +var _format = _interopRequireDefault(require("./format")); +var _list_layout = require("../constants/list_layout"); +var _integration = require("./integration"); +/* eslint-disable +no-mixed-operators, react/function-component-definition, +prefer-object-spread, camelcase, no-plusplus, prefer-destructuring, +max-len */ + +const getTopic = (_, props) => props.topic; +const getFeature = (_, props) => props.feature; +const getLayout = (state, _) => state.layout; // eslint-disable-line + +const GetCyclicVoltaShiftOffset = exports.GetCyclicVoltaShiftOffset = function GetCyclicVoltaShiftOffset() { + let volammetryData = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; + let curveIdx = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; + if (!volammetryData) return 0.0; + const { + spectraList + } = volammetryData; + const spectra = spectraList[curveIdx]; + if (!spectra) return 0.0; + const { + shift + } = spectra; + const { + ref, + val + } = shift; + if (!ref) return 0.0; + const { + e12 + } = ref; + return e12 - val; +}; +const getShiftOffset = (state, _) => { + // eslint-disable-line + const { + curve, + layout, + cyclicvolta + } = state; + const { + curveIdx + } = curve; + if (layout === _list_layout.LIST_LAYOUT.CYCLIC_VOLTAMMETRY && cyclicvolta) { + return GetCyclicVoltaShiftOffset(cyclicvolta, curveIdx); + } + const { + shift + } = state; + const { + shifts + } = shift; + const selectedShift = shifts[curveIdx]; + if (!selectedShift) { + return 0.0; + } + const { + ref, + peak + } = selectedShift; + return (0, _shift.FromManualToOffset)(ref, peak); +}; +const calcXYK = (xs, ys, maxY, offset) => { + const sp = []; + let k = 0; + for (let i = 0; i < ys.length; i += 1) { + // no-downsample + const x = xs[i] - offset; + const y = ys[i]; + const cy = y / maxY; + if (cy > 0.0) { + k += cy; + } + sp.push({ + x, + y, + k + }); + } + return sp; +}; +const calcXY = (xs, ys, maxY, offset) => { + const sp = []; + for (let i = 0; i < ys.length; i += 1) { + // no-downsample + const x = xs[i] - offset; + const y = ys[i]; + sp.push({ + x, + y + }); + } + return sp; +}; +const convertTopic = (topic, layout, feature, offset) => { + const { + maxY + } = feature; + const xs = topic.x; + const ys = topic.y; + const isItgDisable = _cfg.default.btnCmdIntg(layout); + if (!isItgDisable) return calcXYK(xs, ys, maxY, offset); + return calcXY(xs, ys, maxY, offset); +}; +exports.convertTopic = convertTopic; +const Topic2Seed = exports.Topic2Seed = (0, _reselect.createSelector)(getTopic, getLayout, getFeature, getShiftOffset, convertTopic); +const getOthers = (_, props) => props.comparisons; +const calcRescaleXY = (xs, ys, minY, maxY, show) => { + const sp = []; + if (xs.length < 1) return sp; + const [lowerY, upperY] = [Math.min(...ys), Math.max(...ys)]; + const faktor = (maxY - minY) / (upperY - lowerY); + for (let i = 0; i < ys.length; i += 2) { + // downsample + const x = xs[i]; + const y = (ys[i] - lowerY) * faktor + minY; + sp.push({ + x, + y + }); + } + return { + data: sp, + show + }; +}; +const convertComparisons = (layout, comparisons, feature) => { + const { + minY, + maxY + } = feature; + if (!comparisons || !(_format.default.isIrLayout(layout) || _format.default.isHplcUvVisLayout(layout) || _format.default.isXRDLayout(layout))) return []; + return comparisons.map(c => { + const { + spectra, + show + } = c; + const topic = spectra[0].data[0]; + const xs = topic.x; + const ys = topic.y; + return calcRescaleXY(xs, ys, minY, maxY, show); + }); +}; +const GetComparisons = exports.GetComparisons = (0, _reselect.createSelector)(getLayout, getOthers, getFeature, convertComparisons); +const convertFrequency = (layout, feature) => { + if (['1H', '13C', '19F', '31P', '15N', '29Si'].indexOf(layout) < 0) return false; + const { + observeFrequency + } = feature; + const freq = Array.isArray(observeFrequency) ? observeFrequency[0] : observeFrequency; + return parseFloat(freq) || false; +}; +const ToFrequency = exports.ToFrequency = (0, _reselect.createSelector)(getLayout, getFeature, convertFrequency); +const getThreshold = state => state.threshold ? state.threshold.list[state.curve.curveIdx].value * 1.0 : false; +const Convert2Peak = exports.Convert2Peak = function Convert2Peak(feature, threshold, offset) { + let upThreshold = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false; + let lowThreshold = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false; + const peak = []; + if (!feature || !feature.data) return peak; + const data = feature.data[0]; + const { + maxY, + peakUp, + thresRef, + minY, + upperThres, + lowerThres, + operation + } = feature; + const { + layout + } = operation; + + // if (!Format.isSECLayout(layout) && (upperThres || lowerThres)) { + if ((_format.default.isCyclicVoltaLayout(layout) || _format.default.isCDSLayout(layout)) && (upperThres || lowerThres)) { + let upperThresVal = upThreshold || upperThres; + if (!upperThresVal) { + upperThresVal = 1.0; + } + let lowerThresVal = lowThreshold || lowerThres; + if (!lowerThresVal) { + lowerThresVal = 1.0; + } + const yUpperThres = parseFloat(upperThresVal) / 100.0 * maxY; + const yLowerThres = parseFloat(lowerThresVal) / 100.0 * minY; + const corrOffset = offset || 0.0; + for (let i = 0; i < data.y.length; i += 1) { + const y = data.y[i]; + const overUpperThres = y >= yUpperThres; + const belowThres = y <= yLowerThres; + if (overUpperThres || belowThres) { + const x = data.x[i] - corrOffset; + peak.push({ + x, + y + }); + } + } + return peak; + } + const thresVal = threshold || thresRef; + const yThres = Number.parseFloat((thresVal * maxY / 100.0).toFixed(10)); + const corrOffset = offset || 0.0; + for (let i = 0; i < data.y.length; i += 1) { + const y = data.y[i]; + const overThres = peakUp && Math.abs(y) >= yThres || !peakUp && Math.abs(y) <= yThres; + if (overThres) { + const x = data.x[i] - corrOffset; + peak.push({ + x, + y + }); + } + } + return peak; +}; +const Feature2Peak = exports.Feature2Peak = (0, _reselect.createSelector)(getFeature, getThreshold, getShiftOffset, Convert2Peak); +const Convert2MaxMinPeak = (layout, feature, offset) => { + // eslint-disable-line + const peaks = { + max: [], + min: [], + pecker: [], + refIndex: -1 + }; + if (!_format.default.isCyclicVoltaLayout(layout) || !feature || !feature.data) return null; // eslint-disable-line + // const data = feature.data[0]; // eslint-disable-line + const { + volammetryData + } = feature; + if (volammetryData && volammetryData.length > 0) { + const maxArr = volammetryData.map(peakData => { + // peaks.refIndex = peakData.isRef === true ? idx : -1; + if (peakData.max.x === '') return null; + return { + x: Number(peakData.max.x), + y: Number(peakData.max.y) + }; + }); + const minArr = volammetryData.map(peakData => { + if (peakData.min.x === '') return null; + return { + x: Number(peakData.min.x), + y: Number(peakData.min.y) + }; + }); + const peckerArr = volammetryData.map(peakData => { + if (peakData.pecker.x === '') return null; + return { + x: Number(peakData.pecker.x), + y: Number(peakData.pecker.y) + }; + }); + const refIndex = volammetryData.findIndex(peakData => peakData.isRef === true); + peaks.max = maxArr; + peaks.min = minArr; + peaks.pecker = peckerArr; + peaks.refIndex = refIndex; + return peaks; + } + return peaks; +}; +exports.Convert2MaxMinPeak = Convert2MaxMinPeak; +const Feature2MaxMinPeak = exports.Feature2MaxMinPeak = (0, _reselect.createSelector)(getLayout, getFeature, getShiftOffset, Convert2MaxMinPeak); +const convertThresEndPts = (feature, threshold) => { + const { + maxY, + maxX, + minX, + thresRef + } = feature; + const thresVal = threshold || thresRef || 0; + if (!thresVal || !feature.data) return []; + const yThres = thresVal * maxY / 100.0; + const endPts = [{ + x: minX - 200, + y: yThres + }, { + x: maxX + 200, + y: yThres + }]; + return endPts; +}; +const ToThresEndPts = exports.ToThresEndPts = (0, _reselect.createSelector)(getFeature, getThreshold, convertThresEndPts); +const getShiftPeak = state => { + const { + curve, + shift + } = state; + const { + curveIdx + } = curve; + const { + shifts + } = shift; + const selectedShift = shifts[curveIdx]; + if (!selectedShift) { + return false; + } + return selectedShift.peak; +}; +const convertSfPeaks = (peak, offset) => { + if (!peak || !peak.x) return []; + return [{ + x: peak.x - offset, + y: peak.y + }]; +}; +const ToShiftPeaks = exports.ToShiftPeaks = (0, _reselect.createSelector)(getShiftPeak, getShiftOffset, convertSfPeaks); + +// - - - - - - - - - - - - - - - - - - - - - - +// ExtractJcamp +// - - - - - - - - - - - - - - - - - - - - - - +const readLayout = jcamp => { + const { + xType, + spectra + } = jcamp; + if (xType && _format.default.isNmrLayout(xType)) return xType; + const { + dataType + } = spectra[0]; + if (dataType) { + if (dataType.includes('INFRARED SPECTRUM')) { + return _list_layout.LIST_LAYOUT.IR; + } + if (dataType.includes('RAMAN SPECTRUM')) { + return _list_layout.LIST_LAYOUT.RAMAN; + } + if (dataType.includes('UV/VIS SPECTRUM')) { + if (dataType.includes('HPLC')) { + return _list_layout.LIST_LAYOUT.HPLC_UVVIS; + } + return _list_layout.LIST_LAYOUT.UVVIS; + } + if (dataType.includes('THERMOGRAVIMETRIC ANALYSIS')) { + return _list_layout.LIST_LAYOUT.TGA; + } + if (dataType.includes('DIFFERENTIAL SCANNING CALORIMETRY')) { + return _list_layout.LIST_LAYOUT.DSC; + } + if (dataType.includes('X-RAY DIFFRACTION')) { + return _list_layout.LIST_LAYOUT.XRD; + } + if (dataType.includes('MASS SPECTRUM')) { + return _list_layout.LIST_LAYOUT.MS; + } + if (dataType.includes('CYCLIC VOLTAMMETRY')) { + return _list_layout.LIST_LAYOUT.CYCLIC_VOLTAMMETRY; + } + if (dataType.includes('CIRCULAR DICHROISM SPECTROSCOPY')) { + return _list_layout.LIST_LAYOUT.CDS; + } + if (dataType.includes('SIZE EXCLUSION CHROMATOGRAPHY')) { + return _list_layout.LIST_LAYOUT.SEC; + } + if (dataType.includes('GAS CHROMATOGRAPHY')) { + return _list_layout.LIST_LAYOUT.GC; + } + if (dataType.includes('SORPTION-DESORPTION MEASUREMENT')) { + return _list_layout.LIST_LAYOUT.AIF; + } + if (dataType.includes('Emissions')) { + return _list_layout.LIST_LAYOUT.EMISSIONS; + } + if (dataType.includes('DLS ACF')) { + return _list_layout.LIST_LAYOUT.DLS_ACF; + } + if (dataType.includes('DLS intensity')) { + return _list_layout.LIST_LAYOUT.DLS_INTENSITY; + } + } + return false; +}; +const extrSpectraShare = (spectra, layout) => spectra.map(s => Object.assign({ + layout +}, s)).filter(r => r != null); +const extrSpectraMs = (jcamp, layout) => { + const scanCount = jcamp.info.$CSSCANCOUNT || 1; + const spc = extrSpectraShare(jcamp.spectra.slice(0, scanCount), layout); + let spectra = spc || []; + if (jcamp.info.UNITS && jcamp.info.SYMBOL) { + const units = jcamp.info.UNITS.split(','); + const symbol = jcamp.info.SYMBOL.split(','); + let xUnit = null; + let yUnit = null; + symbol.forEach((sym, idx) => { + const currSymbol = sym.replace(' ', '').toLowerCase(); + if (currSymbol === 'x') { + xUnit = units[idx].trim(); + } else if (currSymbol === 'y') { + yUnit = units[idx].trim(); + } + }); + spectra = spectra.map(sp => { + const spectrum = sp; + if (xUnit) { + spectrum.xUnit = xUnit; + } + if (yUnit) { + spectrum.yUnit = yUnit; + } + return spectrum; + }); + } + return spectra; +}; +const extrSpectraNi = (jcamp, layout) => { + const categorys = jcamp.info.$CSCATEGORY || ['SPECTRUM']; + const targetIdx = categorys.indexOf('SPECTRUM'); + const spectrum = extrSpectraShare(jcamp.spectra, layout)[targetIdx]; + return [spectrum] || [jcamp.spectra[0]]; +}; +const calcThresRef = (s, peakUp) => { + const ys = s && s.data[0].y; + if (!ys) return null; + const ref = peakUp ? Math.min(...ys.map(a => Math.abs(a))) : Math.max(...ys); + return peakUp ? Math.floor(ref * 100 * 100 / s.maxY) / 100 : Math.ceil(ref * 100 * 100 / s.maxY) / 100; +}; +const calcUpperThres = s => { + const ys = s && s.data[0].y; + if (!ys) return null; + const ref = Math.max(...ys); + return Math.floor(ref * 100 * 100 / s.maxY) / 100; +}; +const calcLowerThres = s => { + const ys = s && s.data[0].y; + if (!ys) return null; + const ref = Math.min(...ys); + return Math.ceil(ref * 100 * 100 / s.minY) / 100; +}; +const extractShift = (s, jcamp) => { + const shift = { + selectX: false, + solventName: false, + solventValue: false + }; + if (!s) return shift; + if (s && s.sampleDescription) { + const desc = s.sampleDescription; + const info = desc.split(/;|=/); + return { + selectX: parseFloat(info[1]), + solventName: info[3], + solventValue: parseFloat(info[5]) + }; + } + return { + selectX: parseFloat(jcamp.info.$CSSOLVENTX) || false, + solventName: jcamp.info.$CSSOLVENTNAME || false, + solventValue: parseFloat(jcamp.info.$CSSOLVENTVALUE) || false + }; +}; +const extractVoltammetryData = jcamp => { + const { + info + } = jcamp; + if (!info.$CSCYCLICVOLTAMMETRYDATA) return null; + const regx = /[^0-9.,E,e,-]/g; + const rawData = info.$CSCYCLICVOLTAMMETRYDATA.split('\n'); + const peakStack = rawData.map(line => { + const splittedLine = line.replace(regx, '').split(','); + const isRef = splittedLine.length > 8 && splittedLine[8] === '1'; + return { + max: { + x: splittedLine[0], + y: splittedLine[1] + }, + min: { + x: splittedLine[2], + y: splittedLine[3] + }, + ratio: splittedLine[4], + delta: splittedLine[5], + pecker: { + x: splittedLine[6], + y: splittedLine[7] + }, + isRef + }; + }); + return peakStack; +}; +const buildPeakFeature = function buildPeakFeature(jcamp, layout, peakUp, s, thresRef) { + let upperThres = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : false; + let lowerThres = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : false; + // eslint-disable-line + const { + xType, + info + } = jcamp; + const subTyp = xType ? ` - ${xType}` : ''; + return Object.assign({ + typ: s.dataType + subTyp, + peakUp, + thresRef, + scanCount: +info.$CSSCANCOUNT, + scanAutoTarget: +info.$CSSCANAUTOTARGET, + scanEditTarget: +info.$CSSCANEDITTARGET, + shift: extractShift(s, jcamp), + operation: { + layout, + nucleus: xType || '' + }, + observeFrequency: info['.OBSERVEFREQUENCY'], + solventName: info['.SOLVENTNAME'], + upperThres, + lowerThres, + volammetryData: extractVoltammetryData(jcamp), + scanRate: +info.$CSSCANRATE || 0.1 + }, s); +}; +const maxArray = arr => { + let len = arr.length; + let max = -Infinity; + while (len--) { + max = arr[len] > max ? arr[len] : max; + } + return max; +}; +const calcIntgRefArea = (spectra, stack) => { + if (stack.length === 0) return 1; + const data = spectra[0].data[0]; + const xs = data.x; + const ys = data.y; + const maxY = maxArray(ys); + const xyk = calcXYK(xs, ys, maxY, 0); + const { + xL, + xU, + area + } = stack[0]; + const rawArea = (0, _integration.getArea)(xL, xU, xyk); + const raw2realRatio = rawArea / area; + return { + raw2realRatio + }; +}; +const buildIntegFeature = (jcamp, spectra) => { + const { + $OBSERVEDINTEGRALS, + $OBSERVEDMULTIPLETS + } = jcamp.info; + const regx = /[^0-9.,-]/g; + let stack = []; + if ($OBSERVEDINTEGRALS) { + const its = $OBSERVEDINTEGRALS.split('\n').slice(1); + const itStack = its.map(t => { + const ts = t.replace(regx, '').split(','); + return { + xL: parseFloat(ts[0]), + xU: parseFloat(ts[1]), + area: parseFloat(ts[2]), + absoluteArea: parseFloat(ts[3]) + }; + }); + stack = [...stack, ...itStack]; + } + if ($OBSERVEDMULTIPLETS) { + const mps = $OBSERVEDMULTIPLETS.split('\n'); + const mpStack = mps.map(m => { + const ms = m.replace(regx, '').split(','); + return { + xL: parseFloat(ms[1]), + xU: parseFloat(ms[2]), + area: parseFloat(ms[4]) + }; + }); + stack = [...stack, ...mpStack]; + } + const { + raw2realRatio + } = calcIntgRefArea(spectra, stack); + const mStack = stack.map(st => Object.assign({}, st, { + area: st.area * raw2realRatio + })); + return { + refArea: raw2realRatio, + refFactor: 1, + shift: 0, + stack: mStack, + originStack: stack + }; +}; + +/* +const range = (head, tail, length) => { + const actTail = tail || length - 1; + return ( + Array(actTail - head + 1).fill().map((_, idx) => head + idx) + ); +}; +*/ + +const buildSimFeature = jcamp => { + const { + $CSSIMULATIONPEAKS + } = jcamp.info; + let nmrSimPeaks = $CSSIMULATIONPEAKS ? $CSSIMULATIONPEAKS.split('\n') : []; + nmrSimPeaks = nmrSimPeaks.map(x => parseFloat(x).toFixed(2)); + return { + nmrSimPeaks + }; +}; +const buildMpyFeature = jcamp => { + const { + $OBSERVEDMULTIPLETS, + $OBSERVEDMULTIPLETSPEAKS + } = jcamp.info; + const regx = /[^A-Za-z0-9.,-]/g; + const regxNum = /[^0-9.]/g; + let stack = []; + if (!$OBSERVEDMULTIPLETSPEAKS) return { + stack: [] + }; + const allPeaks = $OBSERVEDMULTIPLETSPEAKS.split('\n').map(p => p.replace(regx, '').split(',')); + if ($OBSERVEDMULTIPLETS) { + const mp = $OBSERVEDMULTIPLETS.split('\n'); + const mpStack = mp.map(m => { + const ms = m.replace(regx, '').split(','); + const idx = ms[0]; + let ys = []; + const peaks = allPeaks.map(p => { + if (p[0] === idx) { + ys = [...ys, parseFloat(p[2])]; + return { + x: parseFloat(p[1]), + y: parseFloat(p[2]) + }; + } + return null; + }).filter(r => r != null); + let js = m.split(','); + js = js[js.length - 1].split(' ').map(j => parseFloat(j.replace(regxNum, ''))).filter(Boolean); + return { + js, + mpyType: ms[6], + xExtent: { + xL: parseFloat(ms[1]), + xU: parseFloat(ms[2]) + }, + yExtent: { + yL: Math.min(...ys), + yU: Math.max(...ys) + }, + peaks + }; + }); + stack = [...stack, ...mpStack]; + } + return { + stack, + shift: 0, + smExtext: false + }; +}; +const isPeakTable = s => s.dataType && (s.dataType.includes('PEAKTABLE') || s.dataType.includes('PEAK ASSIGNMENTS')); +const extrFeaturesNi = (jcamp, layout, peakUp, spectra) => { + const nfs = {}; + const category = jcamp.info.$CSCATEGORY; + if (category) { + const idxEditPeak = category.indexOf('EDIT_PEAK'); + if (idxEditPeak >= 0) { + const sEP = jcamp.spectra[idxEditPeak]; + const thresRef = calcThresRef(sEP, peakUp); + nfs.editPeak = buildPeakFeature(jcamp, layout, peakUp, sEP, thresRef); + } + const idxAutoPeak = category.indexOf('AUTO_PEAK'); + if (idxAutoPeak >= 0) { + const sAP = jcamp.spectra[idxAutoPeak]; + const thresRef = calcThresRef(sAP, peakUp); + nfs.autoPeak = buildPeakFeature(jcamp, layout, peakUp, sAP, thresRef); + } + nfs.integration = buildIntegFeature(jcamp, spectra); + nfs.multiplicity = buildMpyFeature(jcamp); + nfs.simulation = buildSimFeature(jcamp); + return nfs; + } + + // workaround for legacy design + const features = jcamp.spectra.map(s => { + const thresRef = calcThresRef(s, peakUp); + return isPeakTable(s) ? buildPeakFeature(jcamp, layout, peakUp, s, thresRef) : null; + }).filter(r => r != null); + const integration = buildIntegFeature(jcamp, spectra); + const multiplicity = buildMpyFeature(jcamp); + const simulation = buildSimFeature(jcamp); + return { + editPeak: features[0], + autoPeak: features[1], + integration, + multiplicity, + simulation + }; +}; +const getBoundary = s => { + const { + x, + y + } = s.data[0]; + const maxX = Math.max(...x); + const minX = Math.min(...x); + const maxY = Math.max(...y); + const minY = Math.min(...y); + return { + maxX, + minX, + maxY, + minY + }; +}; +const extrFeaturesXrd = (jcamp, layout, peakUp) => { + const base = jcamp.spectra[0]; + const features = jcamp.spectra.map(s => { + const upperThres = _format.default.isXRDLayout(layout) ? 100 : calcUpperThres(s); + const lowerThres = _format.default.isXRDLayout(layout) ? 100 : calcLowerThres(s); + const cpo = buildPeakFeature(jcamp, layout, peakUp, s, 100, upperThres, lowerThres); + const bnd = getBoundary(s); + return Object.assign({}, base, cpo, bnd); + }).filter(r => r != null); + const category = jcamp.info.$CSCATEGORY; + if (category) { + const idxEditPeak = category.indexOf('EDIT_PEAK'); + if (idxEditPeak >= 0) { + const sEP = jcamp.spectra[idxEditPeak]; + const thresRef = calcThresRef(sEP, peakUp); + features.editPeak = buildPeakFeature(jcamp, layout, peakUp, sEP, thresRef); + } + const idxAutoPeak = category.indexOf('AUTO_PEAK'); + if (idxAutoPeak >= 0) { + const sAP = jcamp.spectra[idxAutoPeak]; + const thresRef = calcThresRef(sAP, peakUp); + features.autoPeak = buildPeakFeature(jcamp, layout, peakUp, sAP, thresRef); + } + } + return features; +}; +const extrFeaturesCylicVolta = (jcamp, layout, peakUp) => { + const base = jcamp.spectra[0]; + const features = jcamp.spectra.map(s => { + const upperThres = _format.default.isXRDLayout(layout) ? 100 : calcUpperThres(s); + const lowerThres = _format.default.isXRDLayout(layout) ? 100 : calcLowerThres(s); + const cpo = buildPeakFeature(jcamp, layout, peakUp, s, 100, upperThres, lowerThres); + const bnd = getBoundary(s); + let detector = ''; + let secData = null; + if (_format.default.isSECLayout(layout)) { + const { + info + } = jcamp; + detector = info.$DETECTOR ? info.$DETECTOR : ''; + const { + D, + MN, + MP, + MW + } = info; + secData = { + d: D, + mn: MN, + mp: MP, + mw: MW + }; + } + return Object.assign({}, base, cpo, bnd, { + detector, + secData + }); + }).filter(r => r != null); + return features; +}; +const extrFeaturesMs = (jcamp, layout, peakUp) => { + // const nfs = {}; + // const category = jcamp.info.$CSCATEGORY; + // const scanCount = parseInt(jcamp.info.$CSSCANCOUNT, 10) - 1; + // if (category) { + // const idxEditPeak = category.indexOf('EDIT_PEAK'); + // if (idxEditPeak >= 0) { + // const sEP = jcamp.spectra[idxEditPeak + scanCount]; + // const thresRef = calcThresRef(sEP, peakUp); + // nfs.editPeak = buildPeakFeature(jcamp, layout, peakUp, sEP, thresRef); + // } + // const idxAutoPeak = category.indexOf('AUTO_PEAK'); + // if (idxAutoPeak >= 0) { + // const sAP = jcamp.spectra[idxAutoPeak + scanCount]; + // const thresRef = calcThresRef(sAP, peakUp); + // nfs.autoPeak = buildPeakFeature(jcamp, layout, peakUp, sAP, thresRef); + // } + // return nfs; + // } + // // workaround for legacy design + const thresRef = jcamp.info && jcamp.info.$CSTHRESHOLD * 100 || 5; + const base = jcamp.spectra[0]; + const features = jcamp.spectra.map(s => { + const cpo = buildPeakFeature(jcamp, layout, peakUp, s, +thresRef.toFixed(4)); + const bnd = getBoundary(s); + return Object.assign({}, base, cpo, bnd); + }).filter(r => r != null); + return features; +}; +const extractTemperature = jcamp => { + if ('$CSAUTOMETADATA' in jcamp.info) { + const match = jcamp.info.$CSAUTOMETADATA.match(/TEMPERATURE=([\d.]+)/); + if (match !== null) { + const temperature = match[1]; + return temperature; + } + } + return 'xxx'; +}; +const ExtractJcamp = source => { + const jcamp = _jcampconverter.default.convert(source, { + xy: true, + 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|MELTINGPOINT|TG|\$CSSCANRATE|\$CSSPECTRUMDIRECTION)/ // eslint-disable-line + }); + const layout = readLayout(jcamp); + const peakUp = !_format.default.isIrLayout(layout); + const spectra = _format.default.isMsLayout(layout) ? extrSpectraMs(jcamp, layout) : extrSpectraNi(jcamp, layout); + let features = {}; + if (_format.default.isMsLayout(layout)) { + features = extrFeaturesMs(jcamp, layout, peakUp); + } else if (_format.default.isXRDLayout(layout)) { + features = extrFeaturesXrd(jcamp, layout, peakUp); + const temperature = extractTemperature(jcamp); + return { + spectra, + features, + layout, + temperature + }; + } else if (_format.default.isCyclicVoltaLayout(layout) || _format.default.isSECLayout(layout) || _format.default.isAIFLayout(layout) || _format.default.isCDSLayout(layout) || _format.default.isGCLayout(layout)) { + features = extrFeaturesCylicVolta(jcamp, layout, peakUp); + } else { + features = extrFeaturesNi(jcamp, layout, peakUp, spectra); + if (_format.default.isDSCLayout(layout)) { + const { + info + } = jcamp; + const { + MELTINGPOINT, + TG + } = info; + const dscMetaData = { + meltingPoint: MELTINGPOINT, + tg: TG + }; + features = Object.assign({}, features, { + dscMetaData + }); + } + } + // const features = Format.isMsLayout(layout) + // ? extrFeaturesMs(jcamp, layout, peakUp) + // : ((Format.isXRDLayout(layout) || Format.isCyclicVoltaLayout(layout)) + // ? extrFeaturesXrd(jcamp, layout, peakUp) : extrFeaturesNi(jcamp, layout, peakUp, spectra)); + + return { + spectra, + features, + layout + }; +}; +exports.ExtractJcamp = ExtractJcamp; +const Convert2Scan = (feature, scanSt) => { + const { + scanAutoTarget, + scanEditTarget + } = feature; + const { + target, + isAuto + } = scanSt; + const hasEdit = !!scanEditTarget; + const defaultIdx = isAuto || !hasEdit ? scanAutoTarget : scanEditTarget; + return target || defaultIdx; +}; +exports.Convert2Scan = Convert2Scan; +const Convert2Thres = (feature, thresSt) => { + const value = thresSt.value || feature.thresRef; + return value; +}; +exports.Convert2Thres = Convert2Thres; +const Convert2DValue = exports.Convert2DValue = function Convert2DValue(doubleTheta) { + let lambda = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0.15406; + let isRadian = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true; + let theta = doubleTheta / 2; + if (isRadian) { + theta = theta / 180 * Math.PI; + } + const sinTheta = Math.sin(theta); + const dValue = lambda / (2 * sinTheta); + return dValue; +}; +const GetCyclicVoltaRatio = (y_max_peak, y_min_peak, y_pecker) => { + const firstExpr = Math.abs(y_min_peak) / Math.abs(y_max_peak); + const secondExpr = 0.485 * Math.abs(y_pecker) / Math.abs(y_max_peak); + const ratio = firstExpr + secondExpr + 0.086; + return ratio; +}; +exports.GetCyclicVoltaRatio = GetCyclicVoltaRatio; +const GetCyclicVoltaPeakSeparate = (x_max_peak, x_min_peak) => { + const delta = Math.abs(x_max_peak - x_min_peak); + return delta; +}; +exports.GetCyclicVoltaPeakSeparate = GetCyclicVoltaPeakSeparate; +const GetCyclicVoltaPreviousShift = (cyclicVolta, curveIdx) => { + if (!cyclicVolta) { + return 0.0; + } + const { + spectraList + } = cyclicVolta; + if (spectraList.length <= curveIdx) { + return 0.0; + } + const { + shift, + hasRefPeak + } = spectraList[curveIdx]; + const { + prevValue + } = shift; + return hasRefPeak ? prevValue : -prevValue; +}; +exports.GetCyclicVoltaPreviousShift = GetCyclicVoltaPreviousShift; \ No newline at end of file diff --git a/dist/helpers/compass.js b/dist/helpers/compass.js new file mode 100644 index 00000000..c23573b0 --- /dev/null +++ b/dist/helpers/compass.js @@ -0,0 +1,160 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.TfRescale = exports.MouseMove = exports.MountCompass = exports.ClickCompass = void 0; +var _format = _interopRequireDefault(require("./format")); +var _chem = require("./chem"); +const d3 = require('d3'); +const TfRescale = focus => { + const xt = focus.scales.x; + const yt = focus.scales.y; + return { + xt, + yt + }; +}; +exports.TfRescale = TfRescale; +const fetchPt = (event, focus, xt) => { + // const rawMouseX = focus.isFirefox // WORKAROUND d3.mouse firefox compatibility + // ? d3.event.offsetX + // : d3.mouse(focus.root.node())[0]; + const rawMouseX = d3.pointer(event, focus.root.node())[0]; + const mouseX = xt.invert(rawMouseX); + const bisectDate = d3.bisector(d => +d.x).left; + const dt = focus.data; + const ls = dt.length; + const sortData = ls > 0 && dt[0].x > dt[ls - 1].x ? dt.reverse() : dt; + const idx = bisectDate(sortData, +mouseX); + return sortData[idx]; +}; +const fetchFreePt = (event, focus, xt, yt) => { + // const rawMouseX = focus.isFirefox // WORKAROUND d3.mouse firefox compatibility + // ? d3.event.offsetX + // : d3.mouse(focus.root.node())[0]; + // const rawMouseY = focus.isFirefox // WORKAROUND d3.mouse firefox compatibility + // ? d3.event.offsetY + // : d3.mouse(focus.root.node())[1]; + const rawMouseX = d3.pointer(event, focus.root.node())[0]; + const rawMouseY = d3.pointer(event, focus.root.node())[1]; + const mouseX = xt.invert(rawMouseX); + const mouseY = yt.invert(rawMouseY); + const distance2 = (x1, x2, y1, y2) => { + const dx = x1 - x2; + const dy = y1 - y2; + return dx * dx + dy * dy; + }; + let minDistance = Number.MAX_VALUE; + const dt = focus.data; + let selectPoint = null; + dt.forEach(pt => { + const distance = distance2(pt.x, mouseX, pt.y, mouseY); + if (minDistance > distance) { + minDistance = distance; + selectPoint = pt; + } + }); + return selectPoint; +}; +const MouseMove = (event, focus) => { + const { + xt, + yt + } = TfRescale(focus); + const { + freq, + layout, + wavelength + } = focus; + if (_format.default.isCyclicVoltaLayout(layout)) { + const pt = fetchFreePt(event, focus, xt, yt); + if (pt) { + const tx = xt(pt.x); + const ty = yt(pt.y); + focus.root.select('.compass').attr('transform', `translate(${tx},${ty})`); + focus.root.select('.x-hover-line').attr('y1', 0 - ty).attr('y2', focus.h - ty); + focus.root.select('.cursor-txt').attr('transform', `translate(${tx},${10})`).text(pt.x.toFixed(3)); + if (freq) { + focus.root.select('.cursor-txt-hz').attr('transform', `translate(${tx},${20})`).text(`${(pt.x * freq).toFixed(3)} Hz`); + } else { + focus.root.select('.cursor-txt-hz').text(''); + } + } + } else { + const pt = fetchPt(event, focus, xt); + if (pt) { + const tx = xt(pt.x); + const ty = yt(pt.y); + focus.root.select('.compass').attr('transform', `translate(${tx},${ty})`); + focus.root.select('.x-hover-line').attr('y1', 0 - ty).attr('y2', focus.h - ty); + if (_format.default.isXRDLayout(layout)) { + let dValue = 0.0; + if (wavelength) { + dValue = (0, _chem.Convert2DValue)(pt.x, wavelength.value).toExponential(2); + } else { + dValue = (0, _chem.Convert2DValue)(pt.x).toExponential(2); + } + focus.root.select('.cursor-txt-hz').attr('transform', `translate(${tx},${ty - 30})`).text(`2Theta: ${pt.x.toExponential(2)}, d-value: ${dValue}`); + } else if (_format.default.isTGALayout(layout) || _format.default.isDSCLayout(layout)) { + focus.root.select('.cursor-txt').attr('transform', `translate(${tx},${10})`).text(`X: ${pt.x.toFixed(3)}, Y: ${pt.y.toFixed(3)}`); + } else { + focus.root.select('.cursor-txt').attr('transform', `translate(${tx},${10})`).text(pt.x.toFixed(3)); + if (freq) { + focus.root.select('.cursor-txt-hz').attr('transform', `translate(${tx},${20})`).text(`${(pt.x * freq).toFixed(3)} Hz`); + } else { + focus.root.select('.cursor-txt-hz').text(''); + } + } + } + } +}; +exports.MouseMove = MouseMove; +const ClickCompass = (event, focus) => { + event.stopPropagation(); + event.preventDefault(); + const { + xt, + yt + } = TfRescale(focus); + let pt = fetchPt(event, focus, xt); + const { + layout, + cyclicvoltaSt, + jcampIdx + } = focus; + if (_format.default.isCyclicVoltaLayout(layout)) { + pt = fetchFreePt(event, focus, xt, yt); + const onPeak = false; + if (cyclicvoltaSt) { + const { + spectraList + } = cyclicvoltaSt; + const spectra = spectraList[jcampIdx]; + const voltammetryPeakIdx = spectra.selectedIdx; + focus.clickUiTargetAct(pt, onPeak, voltammetryPeakIdx, jcampIdx); + } else { + focus.clickUiTargetAct(pt, onPeak); + } + } else { + focus.clickUiTargetAct(pt, false); + } +}; +exports.ClickCompass = ClickCompass; +const MountCompass = focus => { + const { + root, + w, + h + } = focus; + const compass = root.append('g').attr('class', 'compass'); + const cursor = root.append('g').attr('class', 'cursor'); + const overlay = root.append('rect').attr('class', 'overlay-focus').attr('width', w).attr('height', h).attr('opacity', 0.0); + compass.append('line').attr('class', 'x-hover-line hover-line').attr('stroke', '#777').attr('stroke-width', 1).attr('stroke-dasharray', 2, 2); + compass.append('circle').attr('r', 4).attr('fill', 'none').attr('stroke', '#777').attr('stroke-width', 2); + cursor.append('text').attr('class', 'cursor-txt').attr('font-family', 'Helvetica').style('font-size', '12px').style('text-anchor', 'middle'); + cursor.append('text').attr('class', 'cursor-txt-hz').attr('font-family', 'Helvetica').style('font-size', '12px').style('text-anchor', 'middle').style('fill', '#D68910'); + overlay.on('mousemove', event => MouseMove(event, focus)).on('click', event => ClickCompass(event, focus)); +}; +exports.MountCompass = MountCompass; \ No newline at end of file diff --git a/dist/helpers/converter.js b/dist/helpers/converter.js new file mode 100644 index 00000000..a5f7c35b --- /dev/null +++ b/dist/helpers/converter.js @@ -0,0 +1,99 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.ToXY = exports.PksEdit = exports.PeckersEdit = exports.IsSame = void 0; +const ToXY = data => { + const length = data ? data.length : 0; + if (length === 0) return []; + let peaks = []; + let i = 0; + for (i = 0; i < length; i += 1) { + const { + x, + y + } = data[i]; + peaks = [...peaks, [x, y]]; + } + return peaks; +}; +exports.ToXY = ToXY; +const IsSame = (one, two) => Math.abs((one - two) * 10000000) < 1.0; +exports.IsSame = IsSame; +const pksRmNeg = (dataPks, editPeakSt) => { + const { + selectedIdx, + peaks + } = editPeakSt; + const selectedEditPeaks = peaks[selectedIdx]; + if (!selectedEditPeaks) { + return dataPks; + } + const { + neg + } = selectedEditPeaks; + if (!neg) { + return dataPks; + } + const negXs = neg.map(n => n.x); + const result = dataPks.map(p => { + const idx = negXs.findIndex(nx => IsSame(nx, p.x)); + return idx >= 0 ? null : p; + }).filter(r => r != null); + return result; +}; +const pksAddPos = (dataPks, editPeakSt) => { + const { + selectedIdx, + peaks + } = editPeakSt; + const selectedEditPeaks = peaks[selectedIdx]; + if (!selectedEditPeaks) { + return dataPks; + } + const { + pos + } = selectedEditPeaks; + if (!pos) { + return dataPks; + } + const posXs = pos.map(p => p.x); + const posPks = dataPks.map(p => { + const idx = posXs.findIndex(px => px === p.x); + return idx >= 0 ? null : p; + }).filter(r => r != null); + const result = [...posPks, ...pos]; + return result; +}; +const PksEdit = exports.PksEdit = function PksEdit(dataPks, editPeakSt) { + let voltammetryPeak = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; + if (voltammetryPeak && voltammetryPeak.length > 0) { + let modDataPks = []; + voltammetryPeak.forEach(peak => { + if (peak.max) { + modDataPks = [...modDataPks, peak.max]; + } + if (peak.min) { + modDataPks = [...modDataPks, peak.min]; + } + }); + modDataPks = modDataPks.sort((a, b) => a.x - b.x); + return modDataPks; + } + let modDataPks = pksAddPos(dataPks, editPeakSt); + modDataPks = pksRmNeg(modDataPks, editPeakSt); + modDataPks = modDataPks.sort((a, b) => a.x - b.x); + return modDataPks; +}; +const PeckersEdit = voltammetryPeak => { + let modDataPeckers = []; + voltammetryPeak.forEach(peak => { + if (peak.pecker) { + modDataPeckers = [...modDataPeckers, peak.pecker]; + } + }); + modDataPeckers = modDataPeckers.sort((a, b) => a.x - b.x); + return modDataPeckers; +}; +exports.PeckersEdit = PeckersEdit; \ No newline at end of file diff --git a/dist/helpers/extractParams.js b/dist/helpers/extractParams.js new file mode 100644 index 00000000..8982d48b --- /dev/null +++ b/dist/helpers/extractParams.js @@ -0,0 +1,86 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.extractParams = void 0; +var _format = _interopRequireDefault(require("./format")); +const getScanIdx = (entity, scanSt) => { + const { + target, + isAuto + } = scanSt; + const { + features, + spectra + } = entity; + const defaultFeat = features.editPeak || features.autoPeak || features[0]; + const hasEdit = !!defaultFeat.scanEditTarget; + const defaultIdx = isAuto || !hasEdit ? defaultFeat.scanAutoTarget : defaultFeat.scanEditTarget; + const defaultCount = +spectra.length; + let idx = +(target || defaultIdx || 0); + if (idx > defaultCount) { + idx = defaultCount; + } + return idx - 1; +}; +const extrShare = function extrShare(entity, thresSt) { + let scanIdx = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0; + const { + spectra, + features + } = entity; + // const { autoPeak, editPeak } = features; // TBD + const autoPeak = features.autoPeak || features[scanIdx] || features[0]; + const editPeak = features.editPeak || features[scanIdx] || features[0]; + const hasEdit = editPeak && editPeak.data ? editPeak.data[0].x.length > 0 : false; + const feature = hasEdit && thresSt.isEdit ? editPeak : autoPeak; + const { + integration, + multiplicity + } = features; + return { + spectra, + feature, + hasEdit, + integration, + multiplicity + }; +}; +const extrMs = (entity, thresSt, scanSt) => { + const scanIdx = getScanIdx(entity, scanSt); + const { + spectra, + feature, + hasEdit + } = extrShare(entity, thresSt, scanIdx); + const topic = spectra[scanIdx].data[0]; + return { + topic, + feature, + hasEdit + }; +}; +const extrNi = (entity, thresSt) => { + const scanIdx = 0; + const { + spectra, + feature, + hasEdit, + integration, + multiplicity + } = extrShare(entity, thresSt, scanIdx); + const topic = spectra[0].data[0]; + return { + topic, + feature, + hasEdit, + integration, + multiplicity + }; +}; +const extractParams = (entity, thresSt, scanSt) => _format.default.isMsLayout(entity.layout) ? extrMs(entity, thresSt, scanSt) : extrNi(entity, thresSt); + +// eslint-disable-line +exports.extractParams = extractParams; \ No newline at end of file diff --git a/dist/helpers/extractPeaksEdit.js b/dist/helpers/extractPeaksEdit.js new file mode 100644 index 00000000..5f9c1cb8 --- /dev/null +++ b/dist/helpers/extractPeaksEdit.js @@ -0,0 +1,76 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.extractPeaksEdit = exports.extractAutoPeaks = exports.extractAreaUnderCurve = void 0; +var _converter = require("./converter"); +var _chem = require("./chem"); +var _shift = require("./shift"); +var _format = _interopRequireDefault(require("./format")); +var _integration = require("./integration"); +const niOffset = function niOffset(shiftSt) { + let atIndex = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; + const { + shifts + } = shiftSt; + const selectedShift = shifts[atIndex]; + if (!selectedShift) { + return 0; + } + const { + ref, + peak + } = selectedShift; + const offset = (0, _shift.FromManualToOffset)(ref, peak); + return offset; +}; +const msOffset = () => 0; +const extractPeaksEdit = exports.extractPeaksEdit = function extractPeaksEdit(feature, editPeakSt, thresSt, shiftSt, layoutSt) { + let atIndex = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 0; + const offset = _format.default.isMsLayout(layoutSt) ? msOffset() : niOffset(shiftSt, atIndex); + const peaks = (0, _chem.Convert2Peak)(feature, thresSt.value, offset); + const peaksEdit = (0, _converter.PksEdit)(peaks, editPeakSt); + return peaksEdit; +}; +const extractAutoPeaks = exports.extractAutoPeaks = function extractAutoPeaks(feature, thresSt, shiftSt, layoutSt) { + let atIndex = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 0; + const offset = _format.default.isMsLayout(layoutSt) ? msOffset() : niOffset(shiftSt, atIndex); + const peaks = (0, _chem.Convert2Peak)(feature, thresSt.value, offset); + return peaks; +}; +const getAUCValue = (integrationSt, layoutSt) => { + const { + refArea, + refFactor, + stack + } = integrationSt; + if (Array.isArray(stack) && stack.length > 0) { + const data = stack.at(-1); + const ignoreRef = _format.default.isHplcUvVisLayout(layoutSt); + return (0, _integration.calcArea)(data, refArea, refFactor, ignoreRef); + } + return 0; +}; +const extractAreaUnderCurve = (allIntegrationSt, presentIntegrationSt, layoutSt) => { + if (_format.default.isHplcUvVisLayout(layoutSt) && Array.isArray(allIntegrationSt) && presentIntegrationSt) { + const results = []; + allIntegrationSt.forEach(inte => { + const { + integrations + } = inte; + const subResults = []; + integrations.forEach(subInte => { + const aucVal = getAUCValue(subInte, layoutSt); + subResults.push(aucVal); + }); + results.push(subResults); + }); + return results; + } + return null; +}; + +// eslint-disable-line +exports.extractAreaUnderCurve = extractAreaUnderCurve; \ No newline at end of file diff --git a/dist/helpers/focus.js b/dist/helpers/focus.js new file mode 100644 index 00000000..c48f6dc7 --- /dev/null +++ b/dist/helpers/focus.js @@ -0,0 +1,10 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.mpyIdTag = exports.itgIdTag = void 0; +const itgIdTag = d => `${Math.round(1000 * d.xL)}-${Math.round(1000 * d.xU)}`; +exports.itgIdTag = itgIdTag; +const mpyIdTag = d => `${Math.round(1000 * d.xExtent.xL)}-${Math.round(1000 * d.xExtent.xU)}`; +exports.mpyIdTag = mpyIdTag; \ No newline at end of file diff --git a/dist/helpers/format.js b/dist/helpers/format.js new file mode 100644 index 00000000..1be9527a --- /dev/null +++ b/dist/helpers/format.js @@ -0,0 +1,685 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; +var _jcampconverter = _interopRequireDefault(require("jcampconverter")); +var _converter = require("./converter"); +var _list_layout = require("../constants/list_layout"); +var _multiplicity_calc = require("./multiplicity_calc"); +/* eslint-disable prefer-destructuring */ +/* eslint-disable no-mixed-operators, prefer-object-spread, +function-paren-newline, no-unused-vars, default-param-last */ + +const spectraDigit = layout => { + switch (layout) { + case _list_layout.LIST_LAYOUT.IR: + case _list_layout.LIST_LAYOUT.RAMAN: + case _list_layout.LIST_LAYOUT.UVVIS: + case _list_layout.LIST_LAYOUT.HPLC_UVVIS: + case _list_layout.LIST_LAYOUT.TGA: + case _list_layout.LIST_LAYOUT.DSC: + case _list_layout.LIST_LAYOUT.XRD: + case _list_layout.LIST_LAYOUT.CDS: + case _list_layout.LIST_LAYOUT.SEC: + case _list_layout.LIST_LAYOUT.GC: + case _list_layout.LIST_LAYOUT.MS: + return 0; + case _list_layout.LIST_LAYOUT.C13: + return 1; + case _list_layout.LIST_LAYOUT.H1: + case _list_layout.LIST_LAYOUT.F19: + case _list_layout.LIST_LAYOUT.P31: + case _list_layout.LIST_LAYOUT.N15: + case _list_layout.LIST_LAYOUT.Si29: + case _list_layout.LIST_LAYOUT.PLAIN: + case _list_layout.LIST_LAYOUT.CYCLIC_VOLTAMMETRY: + default: + return 2; + } +}; +const fixDigit = (input, precision) => { + const output = input || 0.0; + return output.toFixed(precision); +}; +const buildData = entity => { + if (!entity) return { + isExist: false + }; + const sp = entity && entity.spectrum; + const xLabel = sp ? `X (${sp.xUnit})` : ''; + const yLabel = sp ? `Y (${sp.yUnit})` : ''; + return { + entity, + xLabel, + yLabel, + isExist: true + }; +}; +const toPeakStr = peaks => { + const arr = peaks.map(p => `${p.x},${p.y}`); + const str = arr.join('#'); + return str; +}; +const spectraOps = { + [_list_layout.LIST_LAYOUT.PLAIN]: { + head: '', + tail: '.' + }, + [_list_layout.LIST_LAYOUT.H1]: { + head: '1H', + tail: '.' + }, + [_list_layout.LIST_LAYOUT.C13]: { + head: '13C', + tail: '.' + }, + [_list_layout.LIST_LAYOUT.F19]: { + head: '19F', + tail: '.' + }, + [_list_layout.LIST_LAYOUT.P31]: { + head: '31P', + tail: '.' + }, + [_list_layout.LIST_LAYOUT.N15]: { + head: '15N', + tail: '.' + }, + [_list_layout.LIST_LAYOUT.Si29]: { + head: '29Si', + tail: '.' + }, + [_list_layout.LIST_LAYOUT.IR]: { + head: 'IR', + tail: ' cm-1' + }, + [_list_layout.LIST_LAYOUT.RAMAN]: { + head: 'RAMAN', + tail: ' cm-1' + }, + [_list_layout.LIST_LAYOUT.UVVIS]: { + head: 'UV-VIS (absorption, solvent), λmax', + tail: ' nm' + }, + [_list_layout.LIST_LAYOUT.HPLC_UVVIS]: { + head: 'HPLC UV/VIS (transmittance)', + tail: '' + }, + [_list_layout.LIST_LAYOUT.TGA]: { + head: 'THERMOGRAVIMETRIC ANALYSIS', + tail: ' SECONDS' + }, + [_list_layout.LIST_LAYOUT.DSC]: { + head: 'DIFFERENTIAL SCANNING CALORIMETRY', + tail: ' SECONDS' + }, + [_list_layout.LIST_LAYOUT.MS]: { + head: 'MASS', + tail: ' m/z' + }, + [_list_layout.LIST_LAYOUT.XRD]: { + head: 'XRD', + tail: '.' + }, + [_list_layout.LIST_LAYOUT.CYCLIC_VOLTAMMETRY]: { + head: 'CV', + tail: '.' + }, + [_list_layout.LIST_LAYOUT.CDS]: { + head: 'CIRCULAR DICHROISM SPECTROSCOPY', + tail: '.' + }, + [_list_layout.LIST_LAYOUT.SEC]: { + head: 'SIZE EXCLUSION CHROMATOGRAPHY', + tail: '.' + }, + [_list_layout.LIST_LAYOUT.GC]: { + head: 'GAS CHROMATOGRAPHY', + tail: '.' + }, + [_list_layout.LIST_LAYOUT.EMISSIONS]: { + head: 'EMISSION', + tail: '.' + }, + [_list_layout.LIST_LAYOUT.DLS_INTENSITY]: { + head: 'DLS', + tail: '.' + } +}; +const rmRef = function rmRef(peaks, shift) { + let atIndex = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0; + if (!shift) return peaks; + const { + shifts + } = shift; + const selectedShift = shifts[atIndex]; + const refValue = selectedShift.ref.value || selectedShift.peak.x; + return peaks.map(p => (0, _converter.IsSame)(p.x, refValue) ? null : p).filter(r => r != null); +}; +const formatedMS = function formatedMS(peaks, maxY) { + let decimal = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 2; + let isAscend = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true; + const ascendFunc = (a, b) => parseFloat(a) - parseFloat(b); + const descendFunc = (a, b) => parseFloat(b) - parseFloat(a); + const sortFunc = isAscend ? ascendFunc : descendFunc; + let ordered = {}; + peaks.forEach(p => { + const x = fixDigit(p.x, decimal); + const better = !ordered[x] || p.y > ordered[x]; + if (better) { + ordered = Object.assign({}, ordered, { + [x]: p.y + }); + } + }); + ordered = Object.keys(ordered).sort(sortFunc).map(k => ({ + x: k, + y: ordered[k] + })); + return ordered.map(o => `${o.x} (${parseInt(100 * o.y / maxY, 10)})`).join(', '); +}; +const emLevel = (boundary, val, lowerIsStronger) => { + const { + maxY, + minY + } = boundary; + const ratio = lowerIsStronger ? 100 * (val - minY) / (maxY - minY) : 100 * (maxY - val) / (maxY - minY); + if (ratio > 85) return 'vw'; + if (ratio > 60) return 'w'; + if (ratio > 45) return 'm'; + if (ratio > 30) return 's'; + return 'vs'; +}; +const formatedEm = function formatedEm(peaks, maxY) { + let decimal = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 2; + let isAscend = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true; + let isIntensity = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false; + let boundary = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : {}; + let lowerIsStronger = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : false; + const ascendFunc = (a, b) => parseFloat(a) - parseFloat(b); + const descendFunc = (a, b) => parseFloat(b) - parseFloat(a); + const sortFunc = isAscend ? ascendFunc : descendFunc; + let ordered = {}; + peaks.forEach(p => { + const x = fixDigit(p.x, decimal); + const better = !ordered[x] || p.y > ordered[x]; + if (better) { + ordered = Object.assign({}, ordered, { + [x]: p.y + }); + } + }); + ordered = Object.keys(ordered).sort(sortFunc).map(k => ({ + x: k, + y: ordered[k] + })); + if (isIntensity) { + return ordered.map(o => `${o.x} (${emLevel(boundary, o.y, lowerIsStronger)})`).join(', '); + } + return ordered.map(o => `${o.x}`).join(', '); +}; +const formatedUvVis = function formatedUvVis(peaks, maxY) { + let decimal = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 2; + let isAscend = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true; + let isIntensity = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false; + let boundary = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : {}; + let lowerIsStronger = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : false; + const ascendFunc = (a, b) => parseFloat(a) - parseFloat(b); + const descendFunc = (a, b) => parseFloat(b) - parseFloat(a); + const sortFunc = isAscend ? ascendFunc : descendFunc; + let ordered = {}; + peaks.forEach(p => { + const x = fixDigit(p.x, decimal); + const better = !ordered[x] || p.y > ordered[x]; + if (better) { + ordered = Object.assign({}, ordered, { + [x]: p.y + }); + } + }); + ordered = Object.keys(ordered).sort(sortFunc).map(k => ({ + x: k, + y: ordered[k] + })); + + // return ordered.map(o => `${o.x} (${o.y.toFixed(2)})`) + // .join(', '); + return ordered.map(o => `${o.x}`).join(', '); +}; +const formatedEmissions = function formatedEmissions(peaks, maxY) { + let decimal = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 2; + let isAscend = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true; + let isIntensity = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false; + let boundary = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : {}; + let lowerIsStronger = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : false; + const ascendFunc = (a, b) => parseFloat(a) - parseFloat(b); + const descendFunc = (a, b) => parseFloat(b) - parseFloat(a); + const sortFunc = isAscend ? ascendFunc : descendFunc; + let ordered = {}; + peaks.forEach(p => { + const x = fixDigit(p.x, decimal); + const better = !ordered[x] || p.y > ordered[x]; + if (better) { + ordered = Object.assign({}, ordered, { + [x]: p.y + }); + } + }); + ordered = Object.keys(ordered).sort(sortFunc).map(k => ({ + x: k, + y: ordered[k] + })); + return ordered.map(o => `${o.x} nm (${fixDigit(o.y, 2)} a.u.)`).join(', '); +}; +const formatedDLSIntensity = function formatedDLSIntensity(peaks, maxY) { + let decimal = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 2; + let isAscend = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true; + let isIntensity = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false; + let boundary = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : {}; + let lowerIsStronger = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : false; + const ascendFunc = (a, b) => parseFloat(a) - parseFloat(b); + const descendFunc = (a, b) => parseFloat(b) - parseFloat(a); + const sortFunc = isAscend ? ascendFunc : descendFunc; + let ordered = {}; + peaks.forEach(p => { + const x = fixDigit(p.x, decimal); + const better = !ordered[x] || p.y > ordered[x]; + if (better) { + ordered = Object.assign({}, ordered, { + [x]: fixDigit(p.y, 2) + }); + } + }); + ordered = Object.keys(ordered).sort(sortFunc).map(k => ({ + x: k, + y: ordered[k] + })); + return ordered.map(o => `${o.x} nm (${o.y} %)`).join(', '); +}; +const formatedHplcUvVis = function formatedHplcUvVis(peaks) { + let decimal = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 2; + let integration = arguments.length > 2 ? arguments[2] : undefined; + let stack = []; + if (integration) { + stack = integration.stack; + } + let ordered = {}; + peaks.forEach(p => { + const x = fixDigit(p.x, decimal); + const better = !ordered[x] || p.y > ordered[x]; + if (better) { + ordered = Object.assign({}, ordered, { + [x]: p.y + }); + } + }); + ordered = Object.keys(ordered).map(k => ({ + x: k, + y: ordered[k] + })); + const arrResult = []; + ordered.forEach(o => { + let pStr = `${o.x} (${o.y.toFixed(2)})`; + if (stack) { + stack.forEach(s => { + if (s.xL <= o.x && s.xU >= o.x) { + pStr = `${o.x} (${o.y.toFixed(2)}, AUC=${s.absoluteArea})`; + } + }); + } + arrResult.push(pStr); + }); + return arrResult.join(', '); +}; +const formatedXRD = function formatedXRD(peaks) { + let isAscend = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; + let waveLength = arguments.length > 2 ? arguments[2] : undefined; + let temperature = arguments.length > 3 ? arguments[3] : undefined; + const ascendFunc = (a, b) => parseFloat(a) - parseFloat(b); + const descendFunc = (a, b) => parseFloat(b) - parseFloat(a); + const sortFunc = isAscend ? ascendFunc : descendFunc; + let ordered = {}; + peaks.forEach(p => { + const x = fixDigit(p.x, 1); + const better = !ordered[x] || p.y > ordered[x]; + if (better) { + ordered = Object.assign({}, ordered, { + [x]: p.y + }); + } + }); + const XRDSource = waveLength.label; + const XRDWavelength = `${waveLength.value} ${waveLength.unit}`; + ordered = Object.keys(ordered).sort(sortFunc).map(k => ({ + x: k, + y: ordered[k] + })); + return `(${XRDSource}, ${XRDWavelength}, ${temperature} °C), 2θ [°] (d [nm]): ${ordered.map(o => `${o.x} (${fixDigit(o.y, 2)})`).join(', ')}`; +}; +const rmShiftFromPeaks = function rmShiftFromPeaks(peaks, shift) { + let atIndex = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0; + const peaksXY = (0, _converter.ToXY)(peaks); + const { + shifts + } = shift; + const selectedShift = shifts[atIndex]; + if (!selectedShift) { + return peaks; + } + // const digit = spectraDigit(layout); + const rmShiftX = selectedShift.ref.value || selectedShift.peak.x; + const result = peaksXY.map(p => { + const srcX = parseFloat(p[0]); + const x = (0, _converter.IsSame)(srcX, rmShiftX) ? null : srcX; + if (!x) return null; + const y = parseFloat(p[1]); + return { + x, + y + }; + }).filter(r => r != null); + return result; +}; +const peaksBody = _ref => { + let { + peaks, + layout, + decimal, + shift, + isAscend, + isIntensity = false, + boundary = {}, + integration, + atIndex = 0, + waveLength, + temperature + } = _ref; + const result = rmShiftFromPeaks(peaks, shift, atIndex); + const ascendFunc = (a, b) => parseFloat(a.x) - parseFloat(b.x); + const descendFunc = (a, b) => parseFloat(b.x) - parseFloat(a.x); + const sortFunc = isAscend ? ascendFunc : descendFunc; + const ordered = result.sort(sortFunc); + const maxY = Math.max(...ordered.map(o => o.y)); + if (layout === _list_layout.LIST_LAYOUT.MS) { + return formatedMS(ordered, maxY, decimal, isAscend); + } + if (layout === _list_layout.LIST_LAYOUT.IR) { + return formatedEm(ordered, maxY, decimal, isAscend, isIntensity, boundary, true); + } + if (layout === _list_layout.LIST_LAYOUT.UVVIS) { + return formatedUvVis(ordered, maxY, decimal, isAscend, isIntensity, boundary, false); + } + if (layout === _list_layout.LIST_LAYOUT.HPLC_UVVIS) { + return formatedHplcUvVis(ordered, decimal, integration); + } + if (layout === _list_layout.LIST_LAYOUT.EMISSIONS) { + return formatedEmissions(ordered, maxY, decimal, isAscend, isIntensity, boundary, false); + } + if (layout === _list_layout.LIST_LAYOUT.DLS_INTENSITY) { + return formatedDLSIntensity(ordered, maxY, decimal, isAscend, isIntensity, boundary, false); + } + if (layout === _list_layout.LIST_LAYOUT.RAMAN || layout === _list_layout.LIST_LAYOUT.TGA || layout === _list_layout.LIST_LAYOUT.DSC || layout === _list_layout.LIST_LAYOUT.CYCLIC_VOLTAMMETRY || layout === _list_layout.LIST_LAYOUT.CDS || layout === _list_layout.LIST_LAYOUT.SEC || layout === _list_layout.LIST_LAYOUT.GC) { + return formatedEm(ordered, maxY, decimal, isAscend, isIntensity, boundary, false); + } + if (layout === _list_layout.LIST_LAYOUT.XRD) { + return formatedXRD(ordered, isAscend, waveLength, temperature); + } + return ordered.map(o => fixDigit(o.x, decimal)).join(', '); +}; +const peaksWrapper = function peaksWrapper(layout, shift) { + let atIndex = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0; + let solvTxt = ''; + const { + shifts + } = shift; + const selectedShift = shifts[atIndex]; + if (selectedShift.ref.label) { + solvTxt = ` (${selectedShift.ref.label})`; + } + if (layout === _list_layout.LIST_LAYOUT.PLAIN || layout === _list_layout.LIST_LAYOUT.DLS_ACF) { + return { + head: '', + tail: '' + }; + } + const ops = spectraOps[layout]; + return { + head: `${ops.head}${solvTxt} = `, + tail: ops.tail + }; +}; +const isNmrLayout = layoutSt => [_list_layout.LIST_LAYOUT.H1, _list_layout.LIST_LAYOUT.C13, _list_layout.LIST_LAYOUT.F19, _list_layout.LIST_LAYOUT.P31, _list_layout.LIST_LAYOUT.N15, _list_layout.LIST_LAYOUT.Si29].indexOf(layoutSt) >= 0; +const is29SiLayout = layoutSt => _list_layout.LIST_LAYOUT.Si29 === layoutSt; +const is15NLayout = layoutSt => _list_layout.LIST_LAYOUT.N15 === layoutSt; +const is31PLayout = layoutSt => _list_layout.LIST_LAYOUT.P31 === layoutSt; +const is19FLayout = layoutSt => _list_layout.LIST_LAYOUT.F19 === layoutSt; +const is13CLayout = layoutSt => _list_layout.LIST_LAYOUT.C13 === layoutSt; +const is1HLayout = layoutSt => _list_layout.LIST_LAYOUT.H1 === layoutSt; +const isMsLayout = layoutSt => _list_layout.LIST_LAYOUT.MS === layoutSt; +const isIrLayout = layoutSt => [_list_layout.LIST_LAYOUT.IR, 'INFRARED'].indexOf(layoutSt) >= 0; +const isRamanLayout = layoutSt => _list_layout.LIST_LAYOUT.RAMAN === layoutSt; +const isUvVisLayout = layoutSt => _list_layout.LIST_LAYOUT.UVVIS === layoutSt; +const isHplcUvVisLayout = layoutSt => _list_layout.LIST_LAYOUT.HPLC_UVVIS === layoutSt; +const isTGALayout = layoutSt => _list_layout.LIST_LAYOUT.TGA === layoutSt; +const isDSCLayout = layoutSt => _list_layout.LIST_LAYOUT.DSC === layoutSt; +const isXRDLayout = layoutSt => _list_layout.LIST_LAYOUT.XRD === layoutSt; +const isCyclicVoltaLayout = layoutSt => _list_layout.LIST_LAYOUT.CYCLIC_VOLTAMMETRY === layoutSt; +const isCDSLayout = layoutSt => _list_layout.LIST_LAYOUT.CDS === layoutSt; +const isSECLayout = layoutSt => _list_layout.LIST_LAYOUT.SEC === layoutSt; +const isGCLayout = layoutSt => _list_layout.LIST_LAYOUT.GC === layoutSt; +const isEmWaveLayout = layoutSt => [_list_layout.LIST_LAYOUT.IR, _list_layout.LIST_LAYOUT.RAMAN, _list_layout.LIST_LAYOUT.UVVIS, _list_layout.LIST_LAYOUT.HPLC_UVVIS].indexOf(layoutSt) >= 0; +const hasMultiCurves = layoutSt => [_list_layout.LIST_LAYOUT.CYCLIC_VOLTAMMETRY, _list_layout.LIST_LAYOUT.SEC, _list_layout.LIST_LAYOUT.GC, _list_layout.LIST_LAYOUT.AIF].indexOf(layoutSt) >= 0; +const isAIFLayout = layoutSt => _list_layout.LIST_LAYOUT.AIF === layoutSt; +const isEmissionsLayout = layoutSt => _list_layout.LIST_LAYOUT.EMISSIONS === layoutSt; +const isDLSACFLayout = layoutSt => _list_layout.LIST_LAYOUT.DLS_ACF === layoutSt; +const isDLSIntensityLayout = layoutSt => _list_layout.LIST_LAYOUT.DLS_INTENSITY === layoutSt; +const getNmrTyp = layout => { + switch (layout) { + case _list_layout.LIST_LAYOUT.H1: + return 'H'; + case _list_layout.LIST_LAYOUT.C13: + return 'C'; + case _list_layout.LIST_LAYOUT.F19: + return 'F'; + case _list_layout.LIST_LAYOUT.P31: + return 'P'; + case _list_layout.LIST_LAYOUT.N15: + return 'N'; + case _list_layout.LIST_LAYOUT.Si29: + return 'Si'; + default: + return ''; + } +}; +const formatPeaksByPrediction = function formatPeaksByPrediction(peaks, layout, isAscend, decimal) { + let predictions = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : []; + const pDict = {}; + peaks.forEach(p => { + pDict[p.x.toFixed(decimal)] = 0; + }); + predictions.forEach(p => { + const key = p.real.toFixed(decimal); + if (typeof pDict[key] === 'number') { + pDict[key] += 1; + } + }); + const typ = getNmrTyp(layout); + const ascendFunc = (a, b) => parseFloat(a.k) - parseFloat(b.k); + const descendFunc = (a, b) => parseFloat(b.k) - parseFloat(a.k); + const sortFunc = isAscend ? ascendFunc : descendFunc; + const pArr = Object.keys(pDict).map(k => { + if (pDict[k] === 1) return { + k, + v: k + }; + return { + k, + v: `${k} (${pDict[k]}${typ})` + }; + }).sort(sortFunc); + const body = pArr.map(p => p.v).join(', '); + return body; +}; +const compareColors = idx => ['#ABB2B9', '#EDBB99', '#ABEBC6', '#D2B4DE', '#F9E79F'][idx % 5]; +const mutiEntitiesColors = idx => ['#2980b9', '#e4b423', '#8e44ad', '#2c3e50', '#6D214F', '#182C61', '#BDC581'][idx % 7]; +const strNumberFixedDecimal = function strNumberFixedDecimal(number) { + let decimal = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : -1; + if (decimal <= 0) { + return `${number}`; + } + return number.toFixed(Math.max(decimal, (number.toString().split('.')[1] || []).length)); +}; +const strNumberFixedLength = function strNumberFixedLength(number) { + let maxLength = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : -1; + if (maxLength <= 0) { + return `${number}`; + } + const splittedNum = number.toString().split('.') || []; + if (splittedNum.length === 0) { + return `${number}`; + } + const integerPart = splittedNum[0]; + if (number >= 0 && maxLength <= integerPart.length || number < 0 && maxLength <= integerPart.length - 1) { + // eslint-disable-line + return `${Math.round(number)}`; + } + const lengthToFix = number >= 0 ? maxLength - integerPart.length : maxLength - integerPart.length + 1; // eslint-disable-line + + return number.toFixed(lengthToFix); +}; +const inlineNotation = function inlineNotation(layout, data) { + let sampleName = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : ''; + let formattedString = ''; + let quillData = []; + const { + scanRate, + voltaData + } = data; + switch (layout) { + case _list_layout.LIST_LAYOUT.CYCLIC_VOLTAMMETRY: + { + if (!voltaData) { + break; + } + let refString = ''; + let nonRefString = ''; + let refOps = []; + const nonRefOps = []; + const { + listPeaks, + xyData + } = voltaData; + const { + x + } = xyData; + listPeaks.forEach(item => { + const { + isRef, + e12, + max, + min + } = item; + const e12Str = e12 ? strNumberFixedLength(e12, 3) : '0'; + const scanRateStr = scanRate ? strNumberFixedLength(scanRate, 3) : '0'; + if (isRef) { + const posNegString = x[0] > x[1] ? 'neg.' : 'pos.'; + refString = `CV ( mM in vs. Ref (Fc+/Fc) = ${e12Str} V, v = ${scanRateStr} V/s, to ${posNegString}):`; + refOps = [{ + insert: 'CV ( mM in vs. Ref ' + }, { + insert: '(Fc' + }, { + insert: '+', + attributes: { + script: 'super' + } + }, { + insert: '/Fc) ' + }, { + insert: `= ${e12Str} V, v = ${scanRateStr} V/s, to ${posNegString}):` + }]; + } else { + const delta = max && min ? strNumberFixedLength(Math.abs(max.x - min.x) * 1000, 3) : '0'; + nonRefString += `\nE1/2 = ([${sampleName}] , ΔEp) = ${e12Str} V (${delta} mV)`; + const currentNoneOps = [{ + insert: '\nE' + }, { + insert: '1/2', + attributes: { + script: 'sub' + } + }, { + insert: ` = ([${sampleName}] , ΔE` + }, { + insert: 'p', + attributes: { + script: 'sub' + } + }, { + insert: `) = ${e12Str} V (${delta} mV)` + }]; + nonRefOps.push(...currentNoneOps); + } + }); + formattedString = refString + nonRefString; + quillData = [...refOps, ...nonRefOps]; + break; + } + default: + break; + } + return { + quillData, + formattedString + }; +}; +const Format = { + toPeakStr, + buildData, + spectraDigit, + spectraOps, + peaksBody, + peaksWrapper, + rmRef, + rmShiftFromPeaks, + isNmrLayout, + is13CLayout, + is1HLayout, + is19FLayout, + is31PLayout, + is15NLayout, + is29SiLayout, + isMsLayout, + isIrLayout, + isRamanLayout, + isUvVisLayout, + isHplcUvVisLayout, + isTGALayout, + isDSCLayout, + isXRDLayout, + isCyclicVoltaLayout, + isCDSLayout, + isSECLayout, + isEmissionsLayout, + isDLSIntensityLayout, + isEmWaveLayout, + isGCLayout, + fixDigit, + formatPeaksByPrediction, + formatedMS, + formatedEm, + calcMpyCenter: _multiplicity_calc.calcMpyCenter, + compareColors, + mutiEntitiesColors, + hasMultiCurves, + isAIFLayout, + isDLSACFLayout, + strNumberFixedDecimal, + formatedXRD, + strNumberFixedLength, + inlineNotation +}; +var _default = exports.default = Format; \ No newline at end of file diff --git a/dist/helpers/init.js b/dist/helpers/init.js new file mode 100644 index 00000000..057121c4 --- /dev/null +++ b/dist/helpers/init.js @@ -0,0 +1,69 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.InitTip = exports.InitScale = exports.InitPathCall = exports.InitAxisCall = void 0; +var _d3Tip = _interopRequireDefault(require("d3-tip")); +var _format = _interopRequireDefault(require("./format")); +const d3 = require('d3'); +const InitScale = exports.InitScale = function InitScale(target) { + let reverse = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; + const xRange = reverse ? [target.w, 0] : [0, target.w]; + const x = d3.scaleLinear().range(xRange); + const y = d3.scaleLinear().range([target.h, 0]); + return { + x, + y + }; +}; +const InitAxisCall = count => { + const yAxisFormat = d3.format('.2n'); + const xAxisCall = d3.axisBottom().ticks(10); + const yAxisCall = d3.axisLeft().ticks(count).tickFormat(yAxisFormat); + return { + x: xAxisCall, + y: yAxisCall + }; +}; +exports.InitAxisCall = InitAxisCall; +const InitPathCall = target => { + const line = d3.line().x(d => target.scales.x(d.x)).y(d => target.scales.y(d.y)); + return line; +}; +exports.InitPathCall = InitPathCall; +const tpStyle = () => { + const stBorder = ' border: 2px solid #aaa;'; + const stBorderRadius = ' border-radius: 5px;'; + const stBackground = ' background: #555;'; + const stColor = ' color: #fff;'; + const stPadding = ' padding: 8px;'; + const stOpacity = ' opacity: 0.9; '; + const stZindex = ' z-index: 1999;'; + const stFontFamily = ' font-family: Helvetica;'; + const style = stBorder + stBorderRadius + stBackground + stColor + stPadding + stOpacity + stPadding + stZindex + stFontFamily; + return style; +}; +const tpDiv = (d, digits) => ` +
+ x: ${_format.default.fixDigit(d.x, digits)} +
+ y: ${d3.format('.2~e')(d.y)} +
+ `; +const InitTip = () => { + d3.select('.peak-tp').remove(); + const tip = (0, _d3Tip.default)().attr('class', 'd3-tip').html(_ref => { + let { + d, + layout + } = _ref; + return tpDiv(d, _format.default.spectraDigit(layout)); + }); + return tip; +}; +exports.InitTip = InitTip; \ No newline at end of file diff --git a/dist/helpers/integration.js b/dist/helpers/integration.js new file mode 100644 index 00000000..b1d59025 --- /dev/null +++ b/dist/helpers/integration.js @@ -0,0 +1,58 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.getArea = exports.getAbsoluteArea = exports.calcArea = void 0; +var _calc = require("./calc"); +/* eslint-disable no-mixed-operators */ + +const getArea = (xL, xU, data) => { + let [iL, iU] = [data.length - 1, 0]; + for (let i = 0; i < data.length; i += 1) { + const pt = data[i]; + if (xL <= pt.x && pt.x <= xU) { + if (iL > i) { + iL = i; + } + if (i > iU) { + iU = i; + } + } + } + return Math.abs(data[iU].k - data[iL].k); +}; +exports.getArea = getArea; +const getAbsoluteArea = (xL, xU, data) => { + const ps = data.filter(d => d.x > xL && d.x < xU); + if (!ps[0]) return 0; + let area = 0; + const point1 = ps[0]; + const point2 = ps[ps.length - 1]; + const slope = (0, _calc.calcSlope)(point1.x, point1.y, point2.x, point2.y); + let lastDY = point1.y; + if (ps.length > 1) { + for (let i = 1; i < ps.length; i += 1) { + const pt = ps[i]; + const lastD = ps[i - 1]; + const y = slope * (pt.x - lastD.x) + lastDY; + lastDY = y; + const delta = Math.abs(pt.y - y); + area += delta; + } + } + return area; +}; +exports.getAbsoluteArea = getAbsoluteArea; +const calcArea = exports.calcArea = function calcArea(d, refArea, refFactor) { + let ignoreRef = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false; + if (ignoreRef) { + const { + absoluteArea + } = d; + return !absoluteArea ? 0 : d.absoluteArea.toFixed(2); + } + return (d.area * refFactor / refArea).toFixed(2); +}; + +// eslint-disable-line \ No newline at end of file diff --git a/dist/helpers/mount.js b/dist/helpers/mount.js new file mode 100644 index 00000000..4f595914 --- /dev/null +++ b/dist/helpers/mount.js @@ -0,0 +1,110 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.MountThresLine = exports.MountTags = exports.MountRef = exports.MountPath = exports.MountMarker = exports.MountMainFrame = exports.MountGrid = exports.MountComparePath = exports.MountClip = exports.MountBars = exports.MountAxisLabelY = exports.MountAxisLabelX = exports.MountAxis = void 0; +var _compass = require("./compass"); +const MountTags = target => { + const igbPath = target.root.append('g').attr('class', 'igbPath-clip').attr('clip-path', 'url(#clip)'); + const igcPath = target.root.append('g').attr('class', 'igcPath-clip').attr('clip-path', 'url(#clip)'); + const igtPath = target.root.append('g').attr('class', 'igtPath-clip').attr('clip-path', 'url(#clip)'); + const pPath = target.root.append('g').attr('class', 'pPath-clip').attr('clip-path', 'url(#clip)'); + const bpPath = target.root.append('g').attr('class', 'bpPath-clip').attr('clip-path', 'url(#clip)'); + const bpTxt = target.root.append('g').attr('class', 'bpTxt-clip').attr('clip-path', 'url(#clip)'); + const mpybPath = target.root.append('g').attr('class', 'mpybPath-clip').attr('clip-path', 'url(#clip)'); + const mpyt1Path = target.root.append('g').attr('class', 'mpyt1Path-clip').attr('clip-path', 'url(#clip)'); + const mpyt2Path = target.root.append('g').attr('class', 'mpyt2Path-clip').attr('clip-path', 'url(#clip)'); + const mpypPath = target.root.append('g').attr('class', 'mpypPath-clip').attr('clip-path', 'url(#clip)'); + const aucPath = target.root.append('g').attr('class', 'aucPath-clip').attr('clip-path', 'url(#clip)'); + const peckerPath = target.root.append('g').attr('class', 'peckerPath-clip').attr('clip-path', 'url(#clip)'); + return { + pPath, + bpPath, + bpTxt, + igbPath, + igcPath, + igtPath, + mpybPath, + mpyt1Path, + mpyt2Path, + mpypPath, + aucPath, + peckerPath // eslint-disable-line + }; +}; +exports.MountTags = MountTags; +const MountBars = target => { + const bars = target.root.append('g').attr('class', 'bars-clip').attr('clip-path', 'url(#clip)'); + return bars; +}; +exports.MountBars = MountBars; +const MountRef = target => { + const ref = target.root.append('g').attr('class', 'ref-clip').attr('clip-path', 'url(#ref-clip)'); + return ref; +}; +exports.MountRef = MountRef; +const MountPath = (target, color) => { + const path = target.root.append('g').attr('class', 'line-clip').attr('clip-path', 'url(#clip)').append('path').attr('class', 'line').style('fill', 'none').style('stroke', color).style('stroke-width', 1).on('click', event => (0, _compass.ClickCompass)(event, target)); + return path; +}; +exports.MountPath = MountPath; +const MountComparePath = exports.MountComparePath = function MountComparePath(target, color, id) { + let alpha = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 1; + const path = target.root.append('g').attr('class', 'line-clip-compare').attr('id', id).attr('clip-path', 'url(#clip)').append('path').attr('class', 'line').style('fill', 'none').style('stroke', color).style('stroke-opacity', alpha).style('stroke-width', 1).style('stroke-dasharray', '30, 3').on('click', event => (0, _compass.ClickCompass)(event, target)); + return path; +}; +const MountThresLine = (target, color) => { + const thresLineUp = target.root.append('g').attr('class', 'line-clip').attr('clip-path', 'url(#clip)').append('path').attr('class', 'thresholdUp').style('stroke-dasharray', '3, 3').style('fill', 'none').style('stroke', color).style('stroke-width', 1); + const thresLineDw = target.root.append('g').attr('class', 'line-clip').attr('clip-path', 'url(#clip)').append('path').attr('class', 'thresholdDw').style('stroke-dasharray', '3, 3').style('fill', 'none').style('stroke', color).style('stroke-width', 1); + return [thresLineUp, thresLineDw]; +}; +exports.MountThresLine = MountThresLine; +const MountGrid = target => { + const gridTrans = `translate(0, ${target.h})`; + const xGrid = target.root.append('g').attr('class', 'x-grid').attr('transform', gridTrans); + const yGrid = target.root.append('g').attr('class', 'y-grid'); + return { + x: xGrid, + y: yGrid + }; +}; +exports.MountGrid = MountGrid; +const MountAxis = target => { + const xAxisTrans = `translate(0, ${target.h})`; + const xAxis = target.root.append('g').attr('class', 'x-axis').attr('transform', xAxisTrans); + const yAxis = target.root.append('g').attr('class', 'y-axis'); + return { + x: xAxis, + y: yAxis + }; +}; +exports.MountAxis = MountAxis; +const MountAxisLabelX = target => { + const xTrans = `translate(${target.w / 2}, ${target.h + 30})`; + target.root.append('text').attr('text-anchor', 'middle').attr('transform', xTrans).attr('class', 'xLabel').attr('font-family', 'Helvetica').style('font-size', '12px'); +}; +exports.MountAxisLabelX = MountAxisLabelX; +const MountAxisLabelY = target => { + const yR = 'rotate(-90)'; + const yTrans = `translate(${16 - target.margin.l}, ${target.h / 2}) ${yR}`; + target.root.append('text').attr('text-anchor', 'middle').attr('transform', yTrans).attr('class', 'yLabel').attr('font-family', 'Helvetica').style('font-size', '12px'); +}; +exports.MountAxisLabelY = MountAxisLabelY; +const MountMarker = (target, color) => { + const tTrans = `translate(${target.w - 80}, -10)`; + const lTrans = `translate(${target.w - 200}, -18)`; + target.root.append('text').attr('text-anchor', 'middle').attr('transform', tTrans).attr('class', 'mark-text').attr('font-family', 'Helvetica'); + target.root.append('rect').attr('transform', lTrans).attr('width', 30).attr('height', 5).attr('class', 'mark-line').style('fill', color); +}; +exports.MountMarker = MountMarker; +const MountClip = target => { + target.svg.append('defs').append('clipPath').attr('id', 'clip').append('rect').attr('width', target.w).attr('height', target.h).attr('x', 0).attr('y', 0); +}; +exports.MountClip = MountClip; +const MountMainFrame = (target, name) => { + const transFrame = `translate(${target.margin.l}, ${target.margin.t})`; + const clsName = `${name}-main`; + target.svg.append('g').attr('class', clsName).attr('transform', transFrame); +}; +exports.MountMainFrame = MountMainFrame; \ No newline at end of file diff --git a/dist/helpers/multiplicity.js b/dist/helpers/multiplicity.js new file mode 100644 index 00000000..c1a420b4 --- /dev/null +++ b/dist/helpers/multiplicity.js @@ -0,0 +1,42 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.mpyBasicPatterns = exports.groupInterval = exports.getInterval = void 0; +const mpyBasicPatterns = exports.mpyBasicPatterns = ['s', 'd', 't', 'q', 'quint', 'h', 'sept', 'o', 'n']; +const getInterval = peaks => { + let itvs = []; + for (let idx = 0; idx < peaks.length - 1; idx += 1) { + const itv = Math.abs(peaks[idx + 1].x - peaks[idx].x); + itvs = [...itvs, itv]; + } + return itvs; +}; +exports.getInterval = getInterval; +const groupInterval = itvs => { + let gitvs = []; + itvs.forEach(vv => { + let applied = false; + gitvs.forEach((gv, idx) => { + if (applied) return; + if (Math.abs((gv.c - vv) / gv.c) <= 0.03) { + const c = (gv.c * gv.es.length + vv) / (gv.es.length + 1); + const es = [...gv.es, vv]; + gitvs = [...gitvs.filter((v, i) => i !== idx), { + c, + es + }]; + applied = true; + } + }); + if (!applied) { + gitvs = [...gitvs, { + c: vv, + es: [vv] + }]; + } + }); + return gitvs; +}; +exports.groupInterval = groupInterval; \ No newline at end of file diff --git a/dist/helpers/multiplicity_calc.js b/dist/helpers/multiplicity_calc.js new file mode 100644 index 00000000..f3bce198 --- /dev/null +++ b/dist/helpers/multiplicity_calc.js @@ -0,0 +1,102 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.calcMpyJStr = exports.calcMpyCoup = exports.calcMpyCenter = void 0; +var _jAnalyzer = _interopRequireDefault(require("../third_party/jAnalyzer")); +var _multiplicity = require("./multiplicity"); +var _multiplicity_verify_basic = require("./multiplicity_verify_basic"); +/* eslint-disable prefer-object-spread, default-param-last */ + +const centerX = (ps, shift) => { + const pxs = ps.map(p => p.x).sort((a, b) => a - b); + const centIdx = (ps.length - 1) / 2; + if (centIdx < 0) return 0; + return pxs[centIdx] - shift; +}; +const calcMpyCenter = (ps, shift, typ) => { + const count = ps.length; + const avgX = ps.reduce((sum, nxt) => sum + nxt.x, 0) / ps.length - shift; + if (typ === 'm') return avgX; + if (count % 2 === 0) return avgX; + return centerX(ps, shift); +}; +exports.calcMpyCenter = calcMpyCenter; +const calcMpyJStr = js => { + if (!Array.isArray(js) || js.length === 0) return ' - '; + const cJ = js.map(j => j.toFixed(3)).join(', '); + return `${cJ}`; +}; +exports.calcMpyJStr = calcMpyJStr; +const calcMpyPeakWidth = (x, metaSt) => { + const { + intervalL, + intervalR, + deltaX + } = metaSt.peaks; + let idxL = null; + intervalL.every((l, idx) => { + if (l.x < x) { + idxL = idx - 1; + return false; + } + return true; + }); + let idxR = null; + intervalR.every((l, idx) => { + if (l.x < x) { + idxR = idx; + return false; + } + return true; + }); + if (!idxL || !idxR) return 10 * deltaX; + return Math.abs(intervalL[idxL].x - intervalR[idxR].x); +}; +const calcMpyCoup = (pks, metaSt) => { + if (pks.length === 0) return { + type: '', + js: '' + }; + const orderPks = pks.sort((a, b) => b.x - a.x); + const { + observeFrequency + } = metaSt.peaks; + const peaks = orderPks.map(p => ({ + x: p.x, + intensity: p.y, + width: calcMpyPeakWidth(p.x, metaSt) + })); + const signal = { + nbPeaks: peaks.length, + observe: observeFrequency, + nucleus: '1H', + peaks + }; + _jAnalyzer.default.compilePattern(signal); + const type = signal.multiplicity; + const js = signal.nmrJs ? signal.nmrJs.map(j => j.coupling).sort() : []; + const isTPCMatch = (0, _multiplicity_verify_basic.verifyTypePeakCount)(type, peaks); + if (!isTPCMatch) return { + type: 'm', + js: [] + }; + if (['s', 'm'].indexOf(type) >= 0) return { + type, + js + }; + const oivs = (0, _multiplicity.getInterval)(orderPks); + if (type === 't') return (0, _multiplicity_verify_basic.verifyTypeT)(type, js, oivs, metaSt); + if (type === 'q') return (0, _multiplicity_verify_basic.verifyTypeQ)(type, js, oivs, metaSt); + if (type === 'quint') return (0, _multiplicity_verify_basic.verifyTypeQuint)(type, js, oivs, metaSt); + if (type === 'h') return (0, _multiplicity_verify_basic.verifyTypeH)(type, js, oivs, metaSt); + if (type === 'sept') return (0, _multiplicity_verify_basic.verifyTypeSept)(type, js, oivs, metaSt); + if (type === 'o') return (0, _multiplicity_verify_basic.verifyTypeO)(type, js, oivs, metaSt); + return { + type, + js + }; +}; +exports.calcMpyCoup = calcMpyCoup; \ No newline at end of file diff --git a/dist/helpers/multiplicity_complat.js b/dist/helpers/multiplicity_complat.js new file mode 100644 index 00000000..66d321ed --- /dev/null +++ b/dist/helpers/multiplicity_complat.js @@ -0,0 +1,100 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.calcMpyComplat = void 0; +var _multiplicity = require("./multiplicity"); +const calcMpyComplat = origPeaks => { + const peaks = origPeaks.sort((a, b) => a.x - b.x); + const count = peaks.length; + const itvs = (0, _multiplicity.getInterval)(peaks); + const gitvs = (0, _multiplicity.groupInterval)(itvs); + let type = 'm'; + let js = []; + switch (count) { + case 1: + type = 's'; + js = []; + break; + case 2: + if (gitvs.length === 1) { + type = 'd'; + js = gitvs.map(g => g.c); + break; + } + break; + case 3: + if (gitvs.length === 1) { + type = 't'; + js = gitvs.map(g => g.c); + break; + } + break; + case 4: + if (gitvs.length === 1) { + type = 'q'; + js = gitvs.map(g => g.c); + break; + } else if (gitvs.length === 2) { + type = 'dd'; + js = gitvs.map(g => g.c); + break; + } + break; + case 5: + if (gitvs.length === 1) { + type = 'quint'; + js = gitvs.map(g => g.c); + break; + } + break; + case 6: + if (gitvs.length === 1) { + type = 'h'; + js = gitvs.map(g => g.c); + break; + } else if (gitvs.length === 2) { + type = 'dt'; + js = gitvs.map(g => g.c); + break; + } + // td + break; + case 7: + if (gitvs.length === 1) { + type = 'sept'; + js = gitvs.map(g => g.c); + break; + } else if (gitvs.length === 3) { + type = 'ddd'; + js = gitvs.map(g => g.c); + break; + } + // td + break; + case 8: + if (gitvs.length === 1) { + type = 'o'; + js = gitvs.map(g => g.c); + break; + } else if (gitvs.length === 2) { + type = 'dq'; + js = gitvs.map(g => g.c); + break; + } else if (gitvs.length === 3) { + type = 'ddd'; + js = gitvs.map(g => g.c); + break; + } + // td + break; + default: + break; + } + return { + type, + js + }; +}; +exports.calcMpyComplat = calcMpyComplat; \ No newline at end of file diff --git a/dist/helpers/multiplicity_manual.js b/dist/helpers/multiplicity_manual.js new file mode 100644 index 00000000..e649508f --- /dev/null +++ b/dist/helpers/multiplicity_manual.js @@ -0,0 +1,125 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.calcMpyManual = void 0; +var _multiplicity = require("./multiplicity"); +/* eslint-disable prefer-object-spread, default-param-last, no-mixed-operators */ + +const isTypeM = mpyType => mpyType === 'm'; +const isTypeBasic = mpyType => _multiplicity.mpyBasicPatterns.slice(1).indexOf(mpyType) >= 0; +const outputTypeM = k => Object.assign({}, k, { + mpyType: 'm', + js: [] +}); +const outputTypeBasic = (k, mpyType, ivs, freq) => { + const numIvs = ivs.length || 1; + const js = [freq * ivs.reduce((sum, x) => sum + x) / numIvs]; + return Object.assign({}, k, { + mpyType, + js + }); +}; +const outputTypeDD = (k, mpyType, ivs, freq) => { + if (ivs.length >= 2) { + const js = [freq * ivs[0], freq * (ivs[0] + ivs[1])]; + return Object.assign({}, k, { + mpyType, + js + }); + } + return Object.assign({}, k, { + mpyType, + js: [] + }); +}; +const outputTypeDT = (k, mpyType, ivs, freq) => { + if (ivs.length >= 4) { + const js = [freq * ivs[0], freq * (ivs[1] + ivs[2] + ivs[3])]; + return Object.assign({}, k, { + mpyType, + js + }); + } + return Object.assign({}, k, { + mpyType, + js: [] + }); +}; +const outputTypeTD = (k, mpyType, ivs, freq) => { + if (ivs.length >= 2) { + const js = [freq * ivs[0], freq * (ivs[0] + ivs[1])]; + return Object.assign({}, k, { + mpyType, + js + }); + } + return Object.assign({}, k, { + mpyType, + js: [] + }); +}; +const outputTypeDQ = (k, mpyType, ivs, freq) => { + if (ivs.length >= 2) { + const js = [freq * ivs[0], freq * (ivs[0] + ivs[1])]; + return Object.assign({}, k, { + mpyType, + js + }); + } // only consider J = ([1,2], [1,3]), not J = ([1,2], [1,5]) + return Object.assign({}, k, { + mpyType, + js: [] + }); +}; +const outputTypeQD = (k, mpyType, ivs, freq) => { + if (ivs.length >= 2) { + const js = [freq * ivs[0], freq * (ivs[0] + ivs[1])]; + return Object.assign({}, k, { + mpyType, + js + }); + } + return Object.assign({}, k, { + mpyType, + js: [] + }); +}; +const outputTypeDDD = (k, mpyType, ivs, freq) => { + if (ivs.length >= 3) { + const js = [freq * ivs[0], freq * (ivs[0] + ivs[1]), freq * (ivs[0] + ivs[1] + ivs[2] + ivs[3])]; + return Object.assign({}, k, { + mpyType, + js + }); + } + return Object.assign({}, k, { + mpyType, + js: [] + }); +}; +const calcMpyManual = (k, mpyType, metaSt) => { + const { + observeFrequency + } = metaSt.peaks; + const freq = observeFrequency || 1.0; + const ivs = (0, _multiplicity.getInterval)(k.peaks); + if (ivs.length === 0) return Object.assign({}, k, { + mpyType, + js: [] + }); + if (isTypeM(mpyType)) return outputTypeM(k); + if (isTypeBasic(mpyType)) return outputTypeBasic(k, mpyType, ivs, freq); + if (mpyType === 'dd') return outputTypeDD(k, mpyType, ivs, freq); + if (mpyType === 'dt') return outputTypeDT(k, mpyType, ivs, freq); + if (mpyType === 'td') return outputTypeTD(k, mpyType, ivs, freq); + if (mpyType === 'dq') return outputTypeDQ(k, mpyType, ivs, freq); + if (mpyType === 'qd') return outputTypeQD(k, mpyType, ivs, freq); + if (mpyType === 'ddd') return outputTypeDDD(k, mpyType, ivs, freq); + return Object.assign({}, k, { + mpyType, + js: [] + }); +}; +exports.calcMpyManual = calcMpyManual; \ No newline at end of file diff --git a/dist/helpers/multiplicity_verify_basic.js b/dist/helpers/multiplicity_verify_basic.js new file mode 100644 index 00000000..f1d7df7a --- /dev/null +++ b/dist/helpers/multiplicity_verify_basic.js @@ -0,0 +1,249 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.verifyTypeT = exports.verifyTypeSept = exports.verifyTypeQuint = exports.verifyTypeQ = exports.verifyTypePeakCount = exports.verifyTypeO = exports.verifyTypeH = void 0; +/* eslint-disable prefer-object-spread, default-param-last, no-mixed-operators */ +// --------------------------------------------------------------- +// verifyTypePeakCount +// --------------------------------------------------------------- + +const verifyTypePeakCount = (type, peaks) => { + const isBasicWrong = type === 's' && peaks.length > 1 || type === 'd' && peaks.length > 2 || type === 't' && peaks.length > 3 || type === 'q' && peaks.length > 4 || type === 'quint' && peaks.length > 5 || type === 'h' && peaks.length > 6 || type === 'sept' && peaks.length > 7 || type === 'o' && peaks.length > 8 || type === 'n' && peaks.length > 9; + let limit = 1; + let mStr = type; + limit *= 5 ** (mStr.match(/quint/g) || []).length; + mStr = mStr.replace(/quint/g, ''); + limit *= 7 ** (mStr.match(/sept/g) || []).length; + mStr = mStr.replace(/sept/g, ''); + limit *= 2 ** (mStr.match(/d/g) || []).length; + mStr = mStr.replace(/d/g, ''); + limit *= 3 ** (mStr.match(/t/g) || []).length; + mStr = mStr.replace(/t/g, ''); + limit *= 4 ** (mStr.match(/q/g) || []).length; + mStr = mStr.replace(/q/g, ''); + limit *= 6 ** (mStr.match(/h/g) || []).length; + mStr = mStr.replace(/h/g, ''); + limit *= 8 ** (mStr.match(/o/g) || []).length; + mStr = mStr.replace(/o/g, ''); + limit *= 9 ** (mStr.match(/n/g) || []).length; + mStr = mStr.replace(/n/g, ''); + const isAdvanWrong = peaks.length > limit; + return !(isBasicWrong || isAdvanWrong); +}; + +// --------------------------------------------------------------- +// Basic Multiplicity verification +// --------------------------------------------------------------- +exports.verifyTypePeakCount = verifyTypePeakCount; +const allowedTolerance = 0.15; +const faktor = 1.1; +const passRuleIntervalCounts = (oivs, limit) => oivs.length === limit; +const getRuleParams = (oivs, metaSt) => { + const { + deltaX, + observeFrequency + } = metaSt.peaks; + const sivs = [...oivs].sort((a, b) => b - a); + const ref = sivs[0]; + const rDeltaX = Math.abs(2 * deltaX / ref); + const tTolerance = rDeltaX > allowedTolerance ? rDeltaX : allowedTolerance; + const tolerance = Math.abs(tTolerance * faktor); + const roivs = oivs.map(oiv => oiv / ref); + const rsivs = sivs.map(siv => siv / ref); + return { + roivs, + rsivs, + tolerance, + observeFrequency + }; +}; +const verifyTypeT = (type, js, oivs, metaSt) => { + if (!passRuleIntervalCounts(oivs, 2)) return { + type: 'm', + js: [] + }; + const { + rsivs, + tolerance + } = getRuleParams(oivs, metaSt); + const isT = Math.abs(rsivs[0] - rsivs[1]) < tolerance; + if (isT) return { + type, + js + }; + return { + type: 'm', + js: [] + }; +}; +exports.verifyTypeT = verifyTypeT; +const verifyTypeQ = (type, js, oivs, metaSt) => { + if (!passRuleIntervalCounts(oivs, 3)) return { + type: 'm', + js: [] + }; + const { + roivs, + rsivs, + tolerance, + observeFrequency + } = getRuleParams(oivs, metaSt); + const isQ = Math.abs(rsivs[0] - rsivs[2]) < tolerance; + if (isQ) return { + type, + js + }; + const isDD = Math.abs(roivs[0] - roivs[2]) < tolerance && Math.abs(roivs[0] - roivs[1]) >= tolerance; + const ddJs = [oivs[0] * observeFrequency, (oivs[0] + oivs[1]) * observeFrequency]; + if (isDD) return { + type: 'dd', + js: ddJs + }; + return { + type: 'm', + js: [] + }; +}; +exports.verifyTypeQ = verifyTypeQ; +const verifyTypeQuint = (type, js, oivs, metaSt) => { + if (!passRuleIntervalCounts(oivs, 4)) return { + type: 'm', + js: [] + }; + const { + rsivs, + tolerance + } = getRuleParams(oivs, metaSt); + const isQuint = Math.abs(rsivs[0] - rsivs[3]) < tolerance; + if (isQuint) return { + type, + js + }; + return { + type: 'm', + js: [] + }; +}; +exports.verifyTypeQuint = verifyTypeQuint; +const verifyTypeH = (type, js, oivs, metaSt) => { + if (!passRuleIntervalCounts(oivs, 5)) return { + type: 'm', + js: [] + }; + const { + roivs, + rsivs, + tolerance, + observeFrequency + } = getRuleParams(oivs, metaSt); + const isH = Math.abs(rsivs[0] - rsivs[4]) < tolerance; + if (isH) return { + type, + js + }; + const isTD = Math.abs(roivs[0] - roivs[2]) < tolerance && Math.abs(roivs[0] - roivs[4]) < tolerance && Math.abs(roivs[1] - roivs[3]) < tolerance && Math.abs(roivs[0] - roivs[1]) >= tolerance; + const tdJs = [oivs[0] * observeFrequency, (oivs[0] + oivs[1]) * observeFrequency]; + if (isTD) return { + type: 'td', + js: tdJs + }; + const isDT1 = Math.abs(roivs[0] - roivs[1]) < tolerance && Math.abs(roivs[0] - roivs[3]) < tolerance && Math.abs(roivs[0] - roivs[4]) < tolerance && Math.abs(roivs[0] - roivs[2]) >= tolerance; + const dt1Js = [oivs[0] * observeFrequency, (oivs[1] + oivs[2] + oivs[3]) * observeFrequency]; + if (isDT1) return { + type: 'dt', + js: dt1Js + }; + const isDT2 = Math.abs(roivs[0] - roivs[4]) < tolerance && Math.abs(roivs[0] - roivs[1] - roivs[2]) < tolerance && Math.abs(roivs[0] - roivs[2] - roivs[3]) < tolerance && Math.abs(roivs[0] - roivs[2]) >= tolerance; + const dt2Js = [oivs[0] * observeFrequency, (oivs[1] + oivs[2] + oivs[3]) * observeFrequency]; + if (isDT2) return { + type: 'dt', + js: dt2Js + }; + return { + type: 'm', + js: [] + }; +}; +exports.verifyTypeH = verifyTypeH; +const verifyTypeSept = (type, js, oivs, metaSt) => { + if (!passRuleIntervalCounts(oivs, 6)) return { + type: 'm', + js: [] + }; + const { + roivs, + rsivs, + tolerance, + observeFrequency + } = getRuleParams(oivs, metaSt); + const isSept = Math.abs(rsivs[0] - rsivs[5]) < tolerance; + if (isSept) return { + type, + js + }; + const isDDD = Math.abs(roivs[0] - roivs[2]) < tolerance && Math.abs(roivs[0] - roivs[3]) < tolerance && Math.abs(roivs[0] - roivs[5]) < tolerance && Math.abs(roivs[1] - roivs[4]) < tolerance && Math.abs(roivs[0] - roivs[1]) >= tolerance; + const dddJs = [oivs[0] * observeFrequency, (oivs[0] + oivs[1]) * observeFrequency, (oivs[0] + oivs[1] + oivs[2]) * observeFrequency]; + if (isDDD) return { + type: 'ddd', + js: dddJs + }; + return { + type: 'm', + js: [] + }; +}; +exports.verifyTypeSept = verifyTypeSept; +const verifyTypeO = (type, js, oivs, metaSt) => { + if (!passRuleIntervalCounts(oivs, 7)) return { + type: 'm', + js: [] + }; + const { + roivs, + rsivs, + tolerance, + observeFrequency + } = getRuleParams(oivs, metaSt); + const isO = Math.abs(rsivs[0] - rsivs[6]) < tolerance; + if (isO) return { + type, + js + }; + const isQD = Math.abs(roivs[0] - roivs[2]) < tolerance && Math.abs(roivs[0] - roivs[4]) < tolerance && Math.abs(roivs[0] - roivs[6]) < tolerance && Math.abs(roivs[1] - roivs[3]) < tolerance && Math.abs(roivs[1] - roivs[5]) < tolerance; + const qdJs = [oivs[0] * observeFrequency, (oivs[0] + oivs[1]) * observeFrequency]; + if (isQD) return { + type: 'qd', + js: qdJs + }; + const isDQ1 = Math.abs(roivs[0] - roivs[1] - roivs[2]) < tolerance && Math.abs(roivs[0] - roivs[2] - roivs[3]) < tolerance && Math.abs(roivs[0] - roivs[3] - roivs[4]) < tolerance && Math.abs(roivs[0] - roivs[4] - roivs[5]) < tolerance && Math.abs(roivs[0] - roivs[6]) < tolerance && Math.abs(roivs[1] - roivs[5]) < tolerance; + const dq1Js = [oivs[0] * observeFrequency, (oivs[0] + oivs[1]) * observeFrequency]; + if (isDQ1) return { + type: 'dq', + js: dq1Js + }; + const isDQ2 = Math.abs(roivs[0] - roivs[1]) < tolerance && Math.abs(roivs[0] - roivs[2]) < tolerance && Math.abs(roivs[0] - roivs[4]) < tolerance && Math.abs(roivs[0] - roivs[5]) < tolerance && Math.abs(roivs[0] - roivs[6]) < tolerance && Math.abs(roivs[0] - roivs[3]) >= tolerance; + const dq2Js = [oivs[0] * observeFrequency, (oivs[0] + oivs[1] + oivs[2] + oivs[3]) * observeFrequency]; + if (isDQ2) return { + type: 'dq', + js: dq2Js + }; + const isDDD1 = Math.abs(roivs[0] - roivs[2]) < tolerance && Math.abs(roivs[0] - roivs[4]) < tolerance && Math.abs(roivs[0] - roivs[6]) < tolerance && Math.abs(roivs[1] - roivs[5]) < tolerance; + const ddd1Js = [oivs[0] * observeFrequency, (oivs[0] + oivs[1]) * observeFrequency, (oivs[0] + oivs[1] + oivs[2] + oivs[3]) * observeFrequency]; + if (isDDD1) return { + type: 'ddd', + js: ddd1Js + }; + const isDDD2 = Math.abs(roivs[0] - roivs[2] - roivs[3]) < tolerance && Math.abs(roivs[0] - roivs[3] - roivs[4]) < tolerance && Math.abs(roivs[0] - roivs[6]) < tolerance && Math.abs(roivs[1] - roivs[5]) < tolerance && Math.abs(roivs[0] - roivs[1]) >= tolerance; + const ddd2Js = [oivs[0] * observeFrequency, (oivs[0] + oivs[1]) * observeFrequency, (oivs[0] + oivs[1] + oivs[2]) * observeFrequency]; + if (isDDD2) return { + type: 'ddd', + js: ddd2Js + }; + return { + type: 'm', + js: [] + }; +}; +exports.verifyTypeO = verifyTypeO; \ No newline at end of file diff --git a/dist/helpers/shift.js b/dist/helpers/shift.js new file mode 100644 index 00000000..917f161e --- /dev/null +++ b/dist/helpers/shift.js @@ -0,0 +1,35 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.VirtalPts = exports.RealPts = exports.FromManualToOffset = exports.CalcResidualX = void 0; +var _list_shift = require("../constants/list_shift"); +/* eslint-disable prefer-object-spread, default-param-last */ + +const shiftNone = _list_shift.LIST_SHIFT_13C[0]; +const FromManualToOffset = (ref, peak) => { + if (!peak || ref.name === shiftNone.name) return 0; + const offset = peak.x - ref.value; + return offset || 0; +}; +exports.FromManualToOffset = FromManualToOffset; +const CalcResidualX = (origRef, origApex, nextApex) => { + if (!nextApex) return 0.0; // nextApex = false + if (origRef.name === shiftNone.name) return 0.0; + const origApexX = origApex ? origApex.x : 0.0; + const origShift = origApexX === 0.0 ? 0.0 : origRef.value; // orig shift + const resX = origShift - origApexX; + return resX; +}; +exports.CalcResidualX = CalcResidualX; +const VirtalPts = (pts, resX) => pts.map(pt => Object.assign({ + x: pt.x + resX, + y: pt.y +})); +exports.VirtalPts = VirtalPts; +const RealPts = (pts, resX) => pts.map(pt => Object.assign({ + x: pt.x - resX, + y: pt.y +})); +exports.RealPts = RealPts; \ No newline at end of file diff --git a/dist/helpers/zoom.js b/dist/helpers/zoom.js new file mode 100644 index 00000000..3fafd924 --- /dev/null +++ b/dist/helpers/zoom.js @@ -0,0 +1,22 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; +const d3 = require('d3'); +const resetZoom = main => { + main.svg.call(main.zoom.transform, d3.zoomIdentity); + main.svg.selectAll('.brush').call(main.brush.move, null); +}; +const MountZoom = (main, zoomed) => { + const zoomedCb = event => zoomed(event, main); + const resetZoomCb = event => { + event.stopPropagation(); + event.preventDefault(); + resetZoom(main); + }; + main.zoom.on('zoom', zoomedCb); + main.svg.call(main.zoom).on('contextmenu.zoom', resetZoomCb); +}; +var _default = exports.default = MountZoom; \ No newline at end of file diff --git a/dist/index.js b/dist/index.js new file mode 100644 index 00000000..d7f7c373 --- /dev/null +++ b/dist/index.js @@ -0,0 +1,859 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); +var _react = _interopRequireDefault(require("react")); +var _reactDom = _interopRequireDefault(require("react-dom")); +var _material = require("@mui/material"); +var _reactQuill = _interopRequireDefault(require("react-quill")); +var _app = require("./app"); +var _nmr1h_jcamp = _interopRequireDefault(require("./__tests__/fixtures/nmr1h_jcamp")); +var _nmr1h_2_jcamp = _interopRequireDefault(require("./__tests__/fixtures/nmr1h_2_jcamp")); +var _nmr13c_dept_jcamp = _interopRequireDefault(require("./__tests__/fixtures/nmr13c_dept_jcamp")); +var _nmr13c_jcamp = _interopRequireDefault(require("./__tests__/fixtures/nmr13c_jcamp")); +var _nmr19f_jcamp = _interopRequireDefault(require("./__tests__/fixtures/nmr19f_jcamp")); +var _nmr31p_jcamp = _interopRequireDefault(require("./__tests__/fixtures/nmr31p_jcamp")); +var _nmr15n_jcamp = _interopRequireDefault(require("./__tests__/fixtures/nmr15n_jcamp")); +var _nmr29si_jcamp = _interopRequireDefault(require("./__tests__/fixtures/nmr29si_jcamp")); +var _ir_jcamp = _interopRequireDefault(require("./__tests__/fixtures/ir_jcamp")); +var _compare_ir_1_jcamp = _interopRequireDefault(require("./__tests__/fixtures/compare_ir_1_jcamp")); +var _compare_ir_2_jcamp = _interopRequireDefault(require("./__tests__/fixtures/compare_ir_2_jcamp")); +var _raman_jcamp = _interopRequireDefault(require("./__tests__/fixtures/raman_jcamp")); +var _ms_jcamp = _interopRequireDefault(require("./__tests__/fixtures/ms_jcamp")); +var _nmr_result = _interopRequireDefault(require("./__tests__/fixtures/nmr_result")); +var _nmr_result_alt = _interopRequireDefault(require("./__tests__/fixtures/nmr_result_alt")); +var _ir_result = _interopRequireDefault(require("./__tests__/fixtures/ir_result")); +var _phenylalanin = _interopRequireDefault(require("./__tests__/fixtures/phenylalanin")); +var _compare_uv_vis_jcamp = _interopRequireDefault(require("./__tests__/fixtures/compare_uv_vis_jcamp")); +var _uv_vis_jcamp = _interopRequireDefault(require("./__tests__/fixtures/uv_vis_jcamp")); +var _hplc_uvvis_jcamp = _interopRequireDefault(require("./__tests__/fixtures/hplc_uvvis_jcamp")); +var _hplc_uvvis_jcamp_ = _interopRequireDefault(require("./__tests__/fixtures/hplc_uvvis_jcamp_2")); +var _tga_jcamp = _interopRequireDefault(require("./__tests__/fixtures/tga_jcamp")); +var _dsc_jcamp = _interopRequireDefault(require("./__tests__/fixtures/dsc_jcamp")); +var _xrd_jcamp_ = _interopRequireDefault(require("./__tests__/fixtures/xrd_jcamp_1")); +var _xrd_jcamp_2 = _interopRequireDefault(require("./__tests__/fixtures/xrd_jcamp_2")); +var _cyclic_voltammetry_ = _interopRequireDefault(require("./__tests__/fixtures/cyclic_voltammetry_1")); +var _cyclic_voltammetry_2 = _interopRequireDefault(require("./__tests__/fixtures/cyclic_voltammetry_2")); +var _cyclic_voltammetry_3 = _interopRequireDefault(require("./__tests__/fixtures/cyclic_voltammetry_3")); +var _cds_jcamp = _interopRequireDefault(require("./__tests__/fixtures/cds_jcamp")); +var _sec_1_jcamp = _interopRequireDefault(require("./__tests__/fixtures/sec_1_jcamp")); +var _sec_2_jcamp = _interopRequireDefault(require("./__tests__/fixtures/sec_2_jcamp")); +var _sec_3_jcamp = _interopRequireDefault(require("./__tests__/fixtures/sec_3_jcamp")); +var _sec_4_jcamp = _interopRequireDefault(require("./__tests__/fixtures/sec_4_jcamp")); +var _aif_jcamp_ = _interopRequireDefault(require("./__tests__/fixtures/aif_jcamp_1")); +var _aif_jcamp_2 = _interopRequireDefault(require("./__tests__/fixtures/aif_jcamp_2")); +var _gc_1_jcamp = _interopRequireDefault(require("./__tests__/fixtures/gc_1_jcamp")); +var _gc_2_jcamp = _interopRequireDefault(require("./__tests__/fixtures/gc_2_jcamp")); +var _gc_3_jcamp = _interopRequireDefault(require("./__tests__/fixtures/gc_3_jcamp")); +var _emissions_jcamp = _interopRequireDefault(require("./__tests__/fixtures/emissions_jcamp")); +var _dls_acf_jcamp = _interopRequireDefault(require("./__tests__/fixtures/dls_acf_jcamp")); +var _dls_intensity_jcamp = _interopRequireDefault(require("./__tests__/fixtures/dls_intensity_jcamp")); +var _qDescValue = require("./__tests__/fixtures/qDescValue"); +require("./__tests__/style/svg.css"); +var _jsxRuntime = require("react/jsx-runtime"); +/* eslint-disable prefer-object-spread, default-param-last, no-nested-ternary */ + +const nmr1HEntity = _app.FN.ExtractJcamp(_nmr1h_jcamp.default); +const nmr1HEntity2 = _app.FN.ExtractJcamp(_nmr1h_2_jcamp.default); +const nmr13CEntity = _app.FN.ExtractJcamp(_nmr13c_jcamp.default); +const nmr13CDeptEntity = _app.FN.ExtractJcamp(_nmr13c_dept_jcamp.default); +const nmr19FEntity = _app.FN.ExtractJcamp(_nmr19f_jcamp.default); +const nmr31PEntity = _app.FN.ExtractJcamp(_nmr31p_jcamp.default); +const nmr15NEntity = _app.FN.ExtractJcamp(_nmr15n_jcamp.default); +const nmr29SiEntity = _app.FN.ExtractJcamp(_nmr29si_jcamp.default); +const irEntity = _app.FN.ExtractJcamp(_ir_jcamp.default); +const compIr1Entity = _app.FN.ExtractJcamp(_compare_ir_1_jcamp.default); +const compIr2Entity = _app.FN.ExtractJcamp(_compare_ir_2_jcamp.default); +const ramanEntity = _app.FN.ExtractJcamp(_raman_jcamp.default); +const msEntity = _app.FN.ExtractJcamp(_ms_jcamp.default); +const uvVisEntity = _app.FN.ExtractJcamp(_uv_vis_jcamp.default); +const compUvVisEntity = _app.FN.ExtractJcamp(_compare_uv_vis_jcamp.default); +const hplcUVVisEntity = _app.FN.ExtractJcamp(_hplc_uvvis_jcamp.default); +const hplcUVVisEntity2 = _app.FN.ExtractJcamp(_hplc_uvvis_jcamp_.default); +const tgaEntity = _app.FN.ExtractJcamp(_tga_jcamp.default); +const dscEntity = _app.FN.ExtractJcamp(_dsc_jcamp.default); +const xrdEntity1 = _app.FN.ExtractJcamp(_xrd_jcamp_.default); +const xrdEntity2 = _app.FN.ExtractJcamp(_xrd_jcamp_2.default); +const cyclicVoltaEntity1 = _app.FN.ExtractJcamp(_cyclic_voltammetry_.default); +const cyclicVoltaEntity2 = _app.FN.ExtractJcamp(_cyclic_voltammetry_2.default); +const cyclicVoltaEntity3 = _app.FN.ExtractJcamp(_cyclic_voltammetry_3.default); +const cdsEntity = _app.FN.ExtractJcamp(_cds_jcamp.default); +const secEntity1 = _app.FN.ExtractJcamp(_sec_1_jcamp.default); +const secEntity2 = _app.FN.ExtractJcamp(_sec_2_jcamp.default); +const secEntity3 = _app.FN.ExtractJcamp(_sec_3_jcamp.default); +const secEntity4 = _app.FN.ExtractJcamp(_sec_4_jcamp.default); +const aifEntity1 = _app.FN.ExtractJcamp(_aif_jcamp_.default); +const aifEntity2 = _app.FN.ExtractJcamp(_aif_jcamp_2.default); +const gcEntity1 = _app.FN.ExtractJcamp(_gc_1_jcamp.default); +const gcEntity2 = _app.FN.ExtractJcamp(_gc_2_jcamp.default); +const gcEntity3 = _app.FN.ExtractJcamp(_gc_3_jcamp.default); +const emissionsEntity = _app.FN.ExtractJcamp(_emissions_jcamp.default); +const dlsAcfEntity = _app.FN.ExtractJcamp(_dls_acf_jcamp.default); +const dlsIntensityEntity = _app.FN.ExtractJcamp(_dls_intensity_jcamp.default); +class DemoWriteIr extends _react.default.Component { + constructor(props) { + super(props); + this.state = { + typ: 'nmr 1h', + desc: '', + predictions: false, + molecule: '', + showOthers: false, + descChanged: '' + }; + this.onClick = this.onClick.bind(this); + this.writeMpy = this.writeMpy.bind(this); + this.writePeak = this.writePeak.bind(this); + this.formatPks = this.formatPks.bind(this); + this.formatMpy = this.formatMpy.bind(this); + this.savePeaks = this.savePeaks.bind(this); + this.predictOp = this.predictOp.bind(this); + this.updatInput = this.updatInput.bind(this); + this.loadEntity = this.loadEntity.bind(this); + this.loadQuill = this.loadQuill.bind(this); + this.onShowOthers = this.onShowOthers.bind(this); + this.loadOthers = this.loadOthers.bind(this); + this.onDescriptionChanged = this.onDescriptionChanged.bind(this); + this.loadMultiEntities = this.loadMultiEntities.bind(this); + } + onClick(typ) { + return () => { + this.setState({ + typ, + desc: '', + predictions: false, + molecule: '' + }); + }; + } + onShowOthers(jcamp) { + // eslint-disable-line + this.setState({ + showOthers: true + }); + } + onDescriptionChanged(content) { + // console.log(content) + this.setState({ + descChanged: content + }); + } + loadEntity() { + const { + typ + } = this.state; + switch (typ) { + case 'nmr 1h': + return nmr1HEntity; + case 'nmr 13c': + return nmr13CEntity; + case 'nmr 13c dept': + return nmr13CDeptEntity; + case 'nmr 19f': + return nmr19FEntity; + case 'nmr 31p': + return nmr31PEntity; + case 'nmr 15n': + return nmr15NEntity; + case 'nmr 29si': + return nmr29SiEntity; + case 'ir': + return irEntity; + case 'raman': + return ramanEntity; + case 'uv/vis': + return uvVisEntity; + case 'hplc uv/vis': + return hplcUVVisEntity; + case 'tga': + return tgaEntity; + case 'dsc': + return dscEntity; + case 'xrd': + return xrdEntity1; + case 'cyclic volta': + return cyclicVoltaEntity2; + case 'cds': + return cdsEntity; + case 'sec': + return secEntity1; + case 'aif': + return aifEntity1; + case 'emissions': + return emissionsEntity; + case 'dls acf': + return dlsAcfEntity; + case 'dls intensity': + return dlsIntensityEntity; + case 'gc': + return gcEntity1; + case 'ms': + default: + return msEntity; + } + } + loadMultiEntities() { + const { + typ + } = this.state; + switch (typ) { + case 'cyclic volta': + return [cyclicVoltaEntity1, cyclicVoltaEntity2, cyclicVoltaEntity3]; + case 'multi': + return [nmr1HEntity, nmr1HEntity2]; + case 'multi hplc': + return [hplcUVVisEntity, hplcUVVisEntity2]; + case 'multi ir': + return [compIr1Entity, compIr2Entity]; + case 'multi xrd': + return [xrdEntity1, xrdEntity2]; + case 'sec': + return [secEntity1, secEntity2, secEntity3, secEntity4]; + case 'aif': + return [aifEntity1, aifEntity2]; + case 'gc': + return [gcEntity1, gcEntity2, gcEntity3]; + default: + return false; + } + } + loadQuill() { + const { + typ + } = this.state; + switch (typ) { + case 'nmr 1h': + return _qDescValue.q1H; + case 'nmr 13c': + return _qDescValue.q13C; + case 'nmr 13c dept': + return _qDescValue.q13C; + case 'ir': + return _qDescValue.qIR; + case 'nmr 19f': + case 'nmr 31p': + case 'nmr 15n': + case 'nmr 29si': + case 'raman': + case 'uv/vis': + case 'hplc uv/vis': + case 'tga': + case 'dsc': + case 'xrd': + case 'ms': + case 'cyclic volta': + case 'cds': + case 'sec': + case 'aif': + case 'emissions': + case 'dls acf': + case 'dls intensity': + case 'gc': + default: + return false; + } + } + loadOthers() { + const { + showOthers, + typ + } = this.state; + const isIr = typ === 'ir' || typ === 'multi ir'; + const isXRD = typ === 'xrd'; + const others = showOthers ? isIr ? [compIr1Entity, compIr2Entity] : isXRD ? [xrdEntity2] : [compUvVisEntity] : []; + return { + others, + addOthersCb: this.onShowOthers + }; + } + rmDollarSign(target) { + return target.replace(/\$/g, ''); + } + formatPks(_ref) { + let { + peaks, + layout, + shift, + isAscend, + decimal, + isIntensity, + integration, + waveLength, + cyclicvoltaSt, + curveSt + } = _ref; + const entity = this.loadEntity(); + const { + features + } = entity; + const { + temperature + } = entity; + const { + maxY, + minY + } = Array.isArray(features) ? {} : features.editPeak || features.autoPeak; + const boundary = { + maxY, + minY + }; + const body = _app.FN.peaksBody({ + peaks, + layout, + decimal, + shift, + isAscend, + isIntensity, + boundary, + integration, + waveLength, + temperature + }); + const wrapper = _app.FN.peaksWrapper(layout, shift); + let desc = this.rmDollarSign(wrapper.head) + body + wrapper.tail; + if (_app.FN.isCyclicVoltaLayout(layout)) { + const { + spectraList + } = cyclicvoltaSt; + const { + curveIdx, + listCurves + } = curveSt; + const selectedVolta = spectraList[curveIdx]; + const selectedCurve = listCurves[curveIdx]; + const { + feature + } = selectedCurve; + const { + scanRate + } = feature; + const data = { + scanRate, + voltaData: { + listPeaks: selectedVolta.list, + xyData: feature.data[0] + } + }; + const inlineData = _app.FN.inlineNotation(layout, data); + const { + formattedString + } = inlineData; + desc = formattedString; + } + return desc; + } + formatMpy(_ref2) { + let { + multiplicity, + integration, + shift, + isAscend, + decimal, + layout + } = _ref2; + // obsv freq + const entity = this.loadEntity(); + const { + features + } = entity; + const { + observeFrequency + } = Array.isArray(features) ? features[0] : features.editPeak || features.autoPeak; + const freq = observeFrequency[0]; + const freqStr = freq ? `${parseInt(freq, 10)} MHz, ` : ''; + // multiplicity + const { + refArea, + refFactor + } = integration; + const shiftVal = multiplicity.shift; + const ms = multiplicity.stack; + const is = integration.stack; + const macs = ms.map(m => { + const { + peaks, + mpyType, + xExtent + } = m; + const { + xL, + xU + } = xExtent; + const it = is.filter(i => i.xL === xL && i.xU === xU)[0] || { + area: 0 + }; + const area = it.area * refFactor / refArea; // eslint-disable-line + const center = _app.FN.calcMpyCenter(peaks, shiftVal, mpyType); + const xs = m.peaks.map(p => p.x).sort((a, b) => a - b); + const [aIdx, bIdx] = isAscend ? [0, xs.length - 1] : [xs.length - 1, 0]; + const mxA = mpyType === 'm' ? (xs[aIdx] - shiftVal).toFixed(decimal) : 0; + const mxB = mpyType === 'm' ? (xs[bIdx] - shiftVal).toFixed(decimal) : 0; + return Object.assign({}, m, { + area, + center, + mxA, + mxB + }); + }).sort((a, b) => isAscend ? a.center - b.center : b.center - a.center); + const str = macs.map(m => { + const c = m.center; + const type = m.mpyType; + const it = Math.round(m.area); + const js = m.js.map(j => `J = ${j.toFixed(1)} Hz`).join(', '); + const atomCount = layout === '1H' ? `, ${it}H` : ''; + const location = type === 'm' ? `${m.mxA}–${m.mxB}` : `${c.toFixed(decimal)}`; + return m.js.length === 0 ? `${location} (${type}${atomCount})` : `${location} (${type}, ${js}${atomCount})`; + }).join(', '); + const { + label, + value, + name + } = shift.ref; + const solvent = label ? `${name.split('(')[0].trim()} [${value.toFixed(decimal)} ppm], ` : ''; + return `${layout} NMR (${freqStr}${solvent}ppm) δ = ${str}.`; + } + writeMpy(_ref3) { + let { + layout, + shift, + isAscend, + decimal, + multiplicity, + integration + } = _ref3; + if (!_app.FN.isNmrLayout(layout)) return; + const desc = this.formatMpy({ + multiplicity, + integration, + shift, + isAscend, + decimal, + layout + }); + this.setState({ + desc + }); + } + writePeak(_ref4) { + let { + peaks, + layout, + shift, + isAscend, + decimal, + isIntensity, + integration, + waveLength, + cyclicvoltaSt, + curveSt + } = _ref4; + const desc = this.formatPks({ + peaks, + layout, + shift, + isAscend, + decimal, + isIntensity, + integration, + waveLength, + // eslint-disable-line + cyclicvoltaSt, + curveSt // eslint-disable-line + }); + this.setState({ + desc + }); + } + savePeaks(_ref5) { + let { + peaks, + layout, + shift, + isAscend, + decimal, + analysis, + isIntensity, + integration, + multiplicity, + waveLength + } = _ref5; + const entity = this.loadEntity(); + const { + features + } = entity; + const { + temperature + } = entity; + const { + maxY, + minY + } = Array.isArray(features) ? features[0] : features.editPeak || features.autoPeak; + const boundary = { + maxY, + minY + }; + const body = _app.FN.peaksBody({ + peaks, + layout, + decimal, + shift, + isAscend, + isIntensity, + boundary, + waveLength, + temperature + }); + /*eslint-disable */ + console.log(analysis); + console.log(integration); + console.log(multiplicity); + if (shift.ref.label) { + const label = this.rmDollarSign(shift.ref.label); + alert(`Peaks: ${body}` + '\n' + '- - - - - - - - - - -' + '\n' + `Shift solvent = ${label}, ${shift.ref.value}ppm` + '\n'); + } else { + alert(`Peaks: ${body}` + '\n'); + } + /*eslint-disable */ + } + predictOp(_ref6) { + let { + multiplicity, + curveSt + } = _ref6; + const { + curveIdx = 0 + } = curveSt || {}; + const { + multiplicities + } = multiplicity; + const selectedMultiplicity = multiplicities[curveIdx]; + const { + stack, + shift + } = selectedMultiplicity; + const targets = stack.map(stk => { + const { + mpyType, + peaks + } = stk; + return _app.FN.CalcMpyCenter(peaks, shift, mpyType); + }); + // console.log(targets) + const { + molecule, + typ + } = this.state; + const predictions = { + running: true, + curveIdx + }; + this.setState({ + predictions + }); + // simulate fetching... + const selectNmrResult = idx => idx % 2 === 0 ? _nmr_result.default : _nmr_result_alt.default; + const result = typ === 'ir' || typ === 'multi ir' ? _ir_result.default : selectNmrResult(curveIdx); + setTimeout(() => { + this.setState({ + predictions: { + ...result, + curveIdx + } + }); + }, 2000); + } + updatInput(e) { + const molecule = e.target.value; + this.setState({ + molecule + }); + } + render() { + const { + desc, + predictions, + molecule, + typ + } = this.state; + const entity = this.loadEntity(); + const qDescVal = this.loadQuill(); + const multiEntities = this.loadMultiEntities(); + let operations = [{ + name: 'write peaks', + value: this.writePeak + }, { + name: 'save', + value: this.savePeaks + }].filter(r => r.value); + if (_app.FN.isNmrLayout(entity.layout)) { + operations = [{ + name: 'write multiplicity', + value: this.writeMpy + }, ...operations]; + } + const refreshCb = () => alert('Refresch simulation!'); + const forecast = { + btnCb: this.predictOp, + refreshCb, + inputCb: this.updatInput, + molecule: molecule, + predictions + }; + const molSvg = ['nmr 1h', 'ir', 'cyclic volta'].indexOf(typ) >= 0 ? _phenylalanin.default.path : ''; + const others = this.loadOthers(); + return /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", { + style: { + width: Math.round(window.innerWidth * 0.96) + }, + children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)("div", { + style: { + margin: '0 0 15px 55px' + }, + children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Button, { + variant: "contained", + style: { + margin: '0 10px 0 10px' + }, + onClick: this.onClick('nmr 1h'), + children: "NMR 1H" + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Button, { + variant: "contained", + style: { + margin: '0 10px 0 10px' + }, + onClick: this.onClick('nmr 13c'), + children: "NMR 13C" + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Button, { + variant: "contained", + style: { + margin: '0 10px 0 10px' + }, + onClick: this.onClick('nmr 13c dept'), + children: "NMR 13C DEPT" + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Button, { + variant: "contained", + style: { + margin: '0 10px 0 10px' + }, + onClick: this.onClick('nmr 19f'), + children: "NMR 19F" + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Button, { + variant: "contained", + style: { + margin: '0 10px 0 10px' + }, + onClick: this.onClick('nmr 31p'), + children: "NMR 31P" + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Button, { + variant: "contained", + style: { + margin: '0 10px 0 10px' + }, + onClick: this.onClick('nmr 15n'), + children: "NMR 15N" + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Button, { + variant: "contained", + style: { + margin: '0 10px 0 10px' + }, + onClick: this.onClick('nmr 29si'), + children: "NMR 29Si" + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Button, { + variant: "contained", + style: { + margin: '0 10px 0 10px' + }, + onClick: this.onClick('ir'), + children: "IR" + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Button, { + variant: "contained", + style: { + margin: '0 10px 0 10px' + }, + onClick: this.onClick('raman'), + children: "RAMAN" + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Button, { + id: "btn-uv-vis", + variant: "contained", + style: { + margin: '0 10px 0 10px' + }, + onClick: this.onClick('uv/vis'), + children: "UV/VIS" + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Button, { + id: "btn-hplc", + variant: "contained", + style: { + margin: '0 10px 0 10px' + }, + onClick: this.onClick('hplc uv/vis'), + children: "HPLC UV/VIS" + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Button, { + id: "btn-tga", + variant: "contained", + style: { + margin: '0 10px 0 10px' + }, + onClick: this.onClick('tga'), + children: "TGA" + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Button, { + id: "btn-dsc", + variant: "contained", + style: { + margin: '0 10px 0 10px' + }, + onClick: this.onClick('dsc'), + children: "DSC" + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Button, { + id: "btn-xrd", + variant: "contained", + style: { + margin: '0 10px 0 10px' + }, + onClick: this.onClick('xrd'), + children: "XRD" + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Button, { + id: "btn-cv", + variant: "contained", + style: { + margin: '0 10px 0 10px' + }, + onClick: this.onClick('cyclic volta'), + children: "CV" + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Button, { + variant: "contained", + style: { + margin: '0 10px 0 10px' + }, + onClick: this.onClick('cds'), + children: "CDS" + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Button, { + id: "btn-sec", + variant: "contained", + style: { + margin: '0 10px 0 10px' + }, + onClick: this.onClick('sec'), + children: "SEC" + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Button, { + id: "btn-sec", + variant: "contained", + style: { + margin: '0 10px 0 10px' + }, + onClick: this.onClick('gc'), + children: "GC" + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Button, { + id: "btn-sod", + variant: "contained", + style: { + margin: '0 10px 0 10px' + }, + onClick: this.onClick('aif'), + children: "SORPTION-DESORPTION" + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Button, { + variant: "contained", + style: { + margin: '0 10px 0 10px' + }, + onClick: this.onClick('emissions'), + children: "EMISSIONS" + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Button, { + variant: "contained", + style: { + margin: '0 10px 0 10px' + }, + onClick: this.onClick('dls acf'), + children: "DLS ACF" + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Button, { + variant: "contained", + style: { + margin: '0 10px 0 10px' + }, + onClick: this.onClick('dls intensity'), + children: "DLS intensity" + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Button, { + variant: "contained", + style: { + margin: '0 10px 0 10px' + }, + onClick: this.onClick('ms'), + children: "MS" + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Button, { + variant: "contained", + style: { + margin: '0 10px 0 10px' + }, + onClick: this.onClick('multi'), + children: "Multi NMR" + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Button, { + variant: "contained", + style: { + margin: '0 10px 0 10px' + }, + onClick: this.onClick('multi ir'), + children: "Multi IR" + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Button, { + variant: "contained", + style: { + margin: '0 10px 0 10px' + }, + onClick: this.onClick('multi hplc'), + children: "Multi HPLC" + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Button, { + variant: "contained", + style: { + margin: '0 10px 0 10px' + }, + onClick: this.onClick('multi xrd'), + children: "Multi XRD" + })] + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_app.SpectraEditor, { + entity: entity, + multiEntities: multiEntities, + others: others, + editorOnly: false, + descriptions: desc, + canChangeDescription: true, + onDescriptionChanged: this.onDescriptionChanged, + molSvg: molSvg, + exactMass: '123.0', + userManualLink: { + cv: "https://www.chemotion.net/chemotionsaurus/docs/eln/chemspectra/cvanalysis" + }, + forecast: forecast, + operations: operations + }), /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", { + children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("span", { + children: "Description Changed" + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactQuill.default, { + className: 'card-sv-quill', + value: this.state.descChanged, + modules: { + toolbar: false + }, + readOnly: true + })] + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Grid, { + container: true, + children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Grid, { + item: true, + xs: 10, + children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.InputBase, { + style: { + margin: '0 0 0 63px' + }, + placeholder: "Description", + multiline: true, + fullWidth: true, + rows: "2", + margin: "dense", + value: desc + }) + }) + })] + }); + } +} + +// - - - DOM - - - +_reactDom.default.render( /*#__PURE__*/(0, _jsxRuntime.jsx)(DemoWriteIr, {}), document.getElementById('root')); \ No newline at end of file diff --git a/dist/layer_content.js b/dist/layer_content.js new file mode 100644 index 00000000..abcffa17 --- /dev/null +++ b/dist/layer_content.js @@ -0,0 +1,105 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; +var _react = _interopRequireDefault(require("react")); +var _propTypes = _interopRequireDefault(require("prop-types")); +var _reactRedux = require("react-redux"); +var _redux = require("redux"); +var _index = _interopRequireDefault(require("./components/d3_line/index")); +var _index2 = _interopRequireDefault(require("./components/d3_rect/index")); +var _forecast_viewer = _interopRequireDefault(require("./components/forecast_viewer")); +var _format = _interopRequireDefault(require("./helpers/format")); +var _jsxRuntime = require("react/jsx-runtime"); +/* eslint-disable prefer-object-spread, default-param-last, react/function-component-definition */ + +const extractLayout = (forecast, layoutSt) => { + const isEmpty = Object.keys(forecast).length === 0 && forecast.constructor === Object; + const isNmr = _format.default.isNmrLayout(layoutSt); + const isMs = _format.default.isMsLayout(layoutSt); + const isIr = _format.default.isIrLayout(layoutSt); + const isUvvis = _format.default.isUvVisLayout(layoutSt) || _format.default.isHplcUvVisLayout(layoutSt); + const isXRD = _format.default.isXRDLayout(layoutSt); + const showForecast = !isEmpty && (isNmr || isIr || isUvvis || isXRD); + return { + showForecast, + isNmr, + isIr, + isMs, + isUvvis, + isXRD + }; +}; +const Content = _ref => { + let { + topic, + feature, + cLabel, + xLabel, + yLabel, + forecast, + operations, + layoutSt + } = _ref; + const { + showForecast, + isNmr, + isIr, + isMs, + isUvvis, + isXRD + } = extractLayout(forecast, layoutSt); + if (showForecast) { + return /*#__PURE__*/(0, _jsxRuntime.jsx)(_forecast_viewer.default, { + topic: topic, + cLabel: cLabel, + xLabel: xLabel, + yLabel: yLabel, + feature: feature, + forecast: forecast, + isNmr: isNmr, + isIr: isIr, + isUvvis: isUvvis, + isXRD: isXRD, + operations: operations + }); + } + if (isMs) { + return /*#__PURE__*/(0, _jsxRuntime.jsx)(_index2.default, { + topic: topic, + cLabel: cLabel, + xLabel: xLabel, + yLabel: yLabel, + feature: feature, + isHidden: false + }); + } + return /*#__PURE__*/(0, _jsxRuntime.jsx)(_index.default, { + topic: topic, + cLabel: cLabel, + xLabel: xLabel, + yLabel: yLabel, + feature: feature, + isHidden: false + }); +}; +const mapStateToProps = (state, _) => ( +// eslint-disable-line +{ + layoutSt: state.layout +}); +const mapDispatchToProps = dispatch => (0, _redux.bindActionCreators)({}, dispatch); +Content.propTypes = { + topic: _propTypes.default.object.isRequired, + feature: _propTypes.default.object.isRequired, + cLabel: _propTypes.default.string.isRequired, + xLabel: _propTypes.default.string.isRequired, + yLabel: _propTypes.default.string.isRequired, + forecast: _propTypes.default.object.isRequired, + operations: _propTypes.default.array.isRequired, + layoutSt: _propTypes.default.string.isRequired +}; +var _default = exports.default = (0, _redux.compose)((0, _reactRedux.connect)(mapStateToProps, mapDispatchToProps))(Content); \ No newline at end of file diff --git a/dist/layer_init.js b/dist/layer_init.js new file mode 100644 index 00000000..44a82363 --- /dev/null +++ b/dist/layer_init.js @@ -0,0 +1,281 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; +var _react = _interopRequireDefault(require("react")); +var _propTypes = _interopRequireDefault(require("prop-types")); +var _reactRedux = require("react-redux"); +var _redux = require("redux"); +var _styles = require("@mui/styles"); +var _submit = require("./actions/submit"); +var _manager = require("./actions/manager"); +var _meta = require("./actions/meta"); +var _jcamp = require("./actions/jcamp"); +var _layer_prism = _interopRequireDefault(require("./layer_prism")); +var _format = _interopRequireDefault(require("./helpers/format")); +var _multi_jcamps_viewer = _interopRequireDefault(require("./components/multi_jcamps_viewer")); +var _curve = require("./actions/curve"); +var _jsxRuntime = require("react/jsx-runtime"); +/* eslint-disable prefer-object-spread, default-param-last */ + +const styles = () => ({}); +class LayerInit extends _react.default.Component { + constructor(props) { + super(props); + this.normChange = this.normChange.bind(this); + this.execReset = this.execReset.bind(this); + this.initReducer = this.initReducer.bind(this); + this.updateOthers = this.updateOthers.bind(this); + this.updateMultiEntities = this.updateMultiEntities.bind(this); + this.hasSameMultiEntities = this.hasSameMultiEntities.bind(this); + } + componentDidMount() { + this.execReset(); + this.initReducer(); + this.updateOthers(); + this.updateMultiEntities(); + } + componentDidUpdate(prevProps) { + this.normChange(prevProps); + this.updateOthers(); + const { + entity, + multiEntities + } = this.props; + const multiEntitiesChanged = !this.hasSameMultiEntities(prevProps.multiEntities, multiEntities); + const entityChanged = prevProps.entity !== entity; + if (multiEntitiesChanged || entityChanged) { + this.updateMultiEntities(); + } + } + normChange(prevProps) { + const { + entity + } = this.props; + if (prevProps.entity !== entity) { + this.execReset(); + } + } + execReset() { + const { + entity, + updateMetaPeaksAct, + resetInitCommonAct, + resetInitMsAct, + resetInitNmrAct, + resetInitCommonWithIntergationAct, + resetDetectorAct, + updateDSCMetaDataAct, + resetMultiplicityAct + } = this.props; + resetInitCommonAct(); + resetDetectorAct(); + const { + layout, + features + } = entity; + if (_format.default.isMsLayout(layout)) { + // const { autoPeak, editPeak } = features; // TBD + const autoPeak = features.autoPeak || features[0]; + const editPeak = features.editPeak || features[0]; + const baseFeat = editPeak || autoPeak; + resetInitMsAct(baseFeat); + } else if (_format.default.isNmrLayout(layout)) { + const { + integration, + multiplicity, + simulation + } = features; + updateMetaPeaksAct(entity); + resetInitNmrAct({ + integration, + multiplicity, + simulation + }); + } else if (_format.default.isHplcUvVisLayout(layout)) { + const { + integration + } = features; + updateMetaPeaksAct(entity); + resetInitCommonWithIntergationAct({ + integration + }); + } else if (_format.default.isDSCLayout(layout)) { + const { + dscMetaData + } = features; + updateDSCMetaDataAct(dscMetaData); + } else { + resetMultiplicityAct(); + } + } + initReducer() { + const { + operations, + updateOperationAct + } = this.props; + updateOperationAct(operations[0]); + } + updateOthers() { + const { + others, + addOthersAct + } = this.props; + addOthersAct(others); + } + hasSameMultiEntities(prevMultiEntities, nextMultiEntities) { + if (prevMultiEntities === nextMultiEntities) return true; + const prevArray = Array.isArray(prevMultiEntities) ? prevMultiEntities : null; + const nextArray = Array.isArray(nextMultiEntities) ? nextMultiEntities : null; + if (!prevArray && !nextArray) return true; + if (!prevArray || !nextArray) return false; + if (prevArray.length !== nextArray.length) return false; + for (let idx = 0; idx < prevArray.length; idx += 1) { + if (prevArray[idx] !== nextArray[idx]) return false; + } + return true; + } + updateMultiEntities() { + const { + multiEntities, + setAllCurvesAct, + entity + } = this.props; + const isMultiSpectra = Array.isArray(multiEntities) && multiEntities.length > 1; + if (isMultiSpectra) { + setAllCurvesAct(multiEntities); + return; + } + if (_format.default.isCyclicVoltaLayout(entity.layout)) { + const payload = Array.isArray(multiEntities) && multiEntities.length > 0 ? multiEntities : [entity]; + setAllCurvesAct(payload); + return; + } + setAllCurvesAct(false); + } + render() { + const { + entity, + cLabel, + xLabel, + yLabel, + forecast, + operations, + descriptions, + molSvg, + editorOnly, + exactMass, + canChangeDescription, + onDescriptionChanged, + multiEntities, + entityFileNames, + userManualLink + } = this.props; + const target = entity.spectra[0]; + const { + layout + } = entity; + const xxLabel = !xLabel && xLabel === '' ? `X (${target.xUnit})` : xLabel; + const yyLabel = !yLabel && yLabel === '' ? `Y (${target.yUnit})` : yLabel; + const isMultiSpectra = Array.isArray(multiEntities) && multiEntities.length > 1; + if (isMultiSpectra) { + return /*#__PURE__*/(0, _jsxRuntime.jsx)(_multi_jcamps_viewer.default, { + multiEntities: multiEntities, + entityFileNames: entityFileNames, + userManualLink: userManualLink, + molSvg: molSvg, + exactMass: exactMass, + operations: operations, + forecast: forecast, + cLabel: cLabel, + descriptions: descriptions, + canChangeDescription: canChangeDescription, + onDescriptionChanged: onDescriptionChanged + }); + } else if (_format.default.isCyclicVoltaLayout(layout)) { + // eslint-disable-line + return /*#__PURE__*/(0, _jsxRuntime.jsx)(_multi_jcamps_viewer.default, { + multiEntities: [entity], + entityFileNames: entityFileNames, + userManualLink: userManualLink, + molSvg: molSvg, + exactMass: exactMass, + operations: operations, + forecast: forecast, + cLabel: cLabel, + descriptions: descriptions, + canChangeDescription: canChangeDescription, + onDescriptionChanged: onDescriptionChanged + }); + } + return /*#__PURE__*/(0, _jsxRuntime.jsx)(_layer_prism.default, { + entity: entity, + cLabel: cLabel, + xLabel: xxLabel, + yLabel: yyLabel, + forecast: forecast, + operations: operations, + descriptions: descriptions, + molSvg: molSvg, + editorOnly: editorOnly, + exactMass: exactMass, + canChangeDescription: canChangeDescription, + onDescriptionChanged: onDescriptionChanged + }); + } +} +const mapStateToProps = (state, props) => ( +// eslint-disable-line +{}); +const mapDispatchToProps = dispatch => (0, _redux.bindActionCreators)({ + resetInitCommonAct: _manager.resetInitCommon, + resetInitNmrAct: _manager.resetInitNmr, + resetInitMsAct: _manager.resetInitMs, + resetInitCommonWithIntergationAct: _manager.resetInitCommonWithIntergation, + resetDetectorAct: _manager.resetDetector, + resetMultiplicityAct: _manager.resetMultiplicity, + updateOperationAct: _submit.updateOperation, + updateMetaPeaksAct: _meta.updateMetaPeaks, + addOthersAct: _jcamp.addOthers, + setAllCurvesAct: _curve.setAllCurves, + updateDSCMetaDataAct: _meta.updateDSCMetaData +}, dispatch); +LayerInit.propTypes = { + entity: _propTypes.default.object.isRequired, + multiEntities: _propTypes.default.array, + // eslint-disable-line + entityFileNames: _propTypes.default.array, + // eslint-disable-line + others: _propTypes.default.object.isRequired, + cLabel: _propTypes.default.string.isRequired, + xLabel: _propTypes.default.string.isRequired, + yLabel: _propTypes.default.string.isRequired, + molSvg: _propTypes.default.string.isRequired, + editorOnly: _propTypes.default.bool.isRequired, + exactMass: _propTypes.default.string.isRequired, + forecast: _propTypes.default.object.isRequired, + operations: _propTypes.default.array.isRequired, + descriptions: _propTypes.default.array.isRequired, + resetInitCommonAct: _propTypes.default.func.isRequired, + resetInitNmrAct: _propTypes.default.func.isRequired, + resetInitMsAct: _propTypes.default.func.isRequired, + resetInitCommonWithIntergationAct: _propTypes.default.func.isRequired, + updateOperationAct: _propTypes.default.func.isRequired, + updateMetaPeaksAct: _propTypes.default.func.isRequired, + addOthersAct: _propTypes.default.func.isRequired, + canChangeDescription: _propTypes.default.bool.isRequired, + onDescriptionChanged: _propTypes.default.func, + // eslint-disable-line + setAllCurvesAct: _propTypes.default.func.isRequired, + userManualLink: _propTypes.default.object, + // eslint-disable-line + resetDetectorAct: _propTypes.default.func.isRequired, + resetMultiplicityAct: _propTypes.default.func.isRequired, + updateDSCMetaDataAct: _propTypes.default.func.isRequired +}; +var _default = exports.default = (0, _reactRedux.connect)( +// eslint-disable-line +mapStateToProps, mapDispatchToProps)((0, _styles.withStyles)(styles)(LayerInit)); // eslint-disable-line \ No newline at end of file diff --git a/dist/layer_prism.js b/dist/layer_prism.js new file mode 100644 index 00000000..c6e5fd01 --- /dev/null +++ b/dist/layer_prism.js @@ -0,0 +1,151 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; +var _react = _interopRequireDefault(require("react")); +var _propTypes = _interopRequireDefault(require("prop-types")); +var _reactRedux = require("react-redux"); +var _redux = require("redux"); +var _Grid = _interopRequireDefault(require("@mui/material/Grid")); +var _styles = require("@mui/styles"); +var _index = _interopRequireDefault(require("./components/panel/index")); +var _index2 = _interopRequireDefault(require("./components/cmd_bar/index")); +var _layer_content = _interopRequireDefault(require("./layer_content")); +var _list_ui = require("./constants/list_ui"); +var _extractParams = require("./helpers/extractParams"); +var _jsxRuntime = require("react/jsx-runtime"); +/* eslint-disable prefer-object-spread, default-param-last, +react/function-component-definition, react/require-default-props +*/ + +const styles = () => ({}); +const LayerPrism = _ref => { + let { + entity, + cLabel, + xLabel, + yLabel, + forecast, + operations, + descriptions, + molSvg, + editorOnly, + exactMass, + thresSt, + scanSt, + uiSt, + canChangeDescription, + onDescriptionChanged + } = _ref; + const { + topic, + feature, + hasEdit, + integration + } = (0, _extractParams.extractParams)(entity, thresSt, scanSt); + if (!topic) return null; + const { + viewer + } = uiSt; + if (viewer === _list_ui.LIST_UI_VIEWER_TYPE.ANALYSIS) { + return /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", { + children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_index2.default, { + feature: feature, + hasEdit: hasEdit, + forecast: forecast, + operations: operations, + editorOnly: editorOnly + }), /*#__PURE__*/(0, _jsxRuntime.jsx)("div", { + className: "react-spectrum-editor", + children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Grid.default, { + container: true, + children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Grid.default, { + item: true, + xs: 12, + children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_layer_content.default, { + topic: topic, + feature: feature, + cLabel: cLabel, + xLabel: xLabel, + yLabel: yLabel, + forecast: forecast, + operations: operations + }) + }) + }) + })] + }); + } + return /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", { + children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_index2.default, { + feature: feature, + hasEdit: hasEdit, + forecast: forecast, + operations: operations, + editorOnly: editorOnly + }), /*#__PURE__*/(0, _jsxRuntime.jsx)("div", { + className: "react-spectrum-editor", + children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_Grid.default, { + container: true, + children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_Grid.default, { + item: true, + xs: 9, + children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_layer_content.default, { + topic: topic, + feature: feature, + cLabel: cLabel, + xLabel: xLabel, + yLabel: yLabel, + forecast: forecast, + operations: operations + }) + }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_Grid.default, { + item: true, + xs: 3, + align: "center", + children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_index.default, { + feature: feature, + integration: integration, + editorOnly: editorOnly, + molSvg: molSvg, + exactMass: exactMass, + descriptions: descriptions, + canChangeDescription: canChangeDescription, + onDescriptionChanged: onDescriptionChanged + }) + })] + }) + })] + }); +}; +const mapStateToProps = (state, props) => ( +// eslint-disable-line +{ + scanSt: state.scan, + thresSt: state.threshold.list[state.curve.curveIdx], + uiSt: state.ui +}); +const mapDispatchToProps = dispatch => (0, _redux.bindActionCreators)({}, dispatch); +LayerPrism.propTypes = { + entity: _propTypes.default.object.isRequired, + cLabel: _propTypes.default.string.isRequired, + xLabel: _propTypes.default.string.isRequired, + yLabel: _propTypes.default.string.isRequired, + molSvg: _propTypes.default.string.isRequired, + editorOnly: _propTypes.default.bool.isRequired, + exactMass: _propTypes.default.string, + forecast: _propTypes.default.object.isRequired, + operations: _propTypes.default.array.isRequired, + descriptions: _propTypes.default.array.isRequired, + thresSt: _propTypes.default.object.isRequired, + scanSt: _propTypes.default.object.isRequired, + uiSt: _propTypes.default.object.isRequired, + canChangeDescription: _propTypes.default.bool.isRequired, + onDescriptionChanged: _propTypes.default.func +}; +var _default = exports.default = (0, _reactRedux.connect)( +// eslint-disable-line +mapStateToProps, mapDispatchToProps)((0, _styles.withStyles)(styles)(LayerPrism)); // eslint-disable-line \ No newline at end of file diff --git a/dist/reducers/index.js b/dist/reducers/index.js new file mode 100644 index 00000000..50868a3b --- /dev/null +++ b/dist/reducers/index.js @@ -0,0 +1,51 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; +var _redux = require("redux"); +var _reducer_threshold = _interopRequireDefault(require("./reducer_threshold")); +var _reducer_edit_peak = _interopRequireDefault(require("./reducer_edit_peak")); +var _reducer_status = _interopRequireDefault(require("./reducer_status")); +var _reducer_manager = _interopRequireDefault(require("./reducer_manager")); +var _reducer_layout = _interopRequireDefault(require("./reducer_layout")); +var _reducer_shift = _interopRequireDefault(require("./reducer_shift")); +var _reducer_scan = _interopRequireDefault(require("./reducer_scan")); +var _reducer_forecast = _interopRequireDefault(require("./reducer_forecast")); +var _reducer_ui = _interopRequireDefault(require("./reducer_ui")); +var _reducer_submit = _interopRequireDefault(require("./reducer_submit")); +var _reducer_integration = _interopRequireDefault(require("./reducer_integration")); +var _reducer_multiplicity = _interopRequireDefault(require("./reducer_multiplicity")); +var _reducer_simulation = _interopRequireDefault(require("./reducer_simulation")); +var _reducer_meta = _interopRequireDefault(require("./reducer_meta")); +var _reducer_jcamp = _interopRequireDefault(require("./reducer_jcamp")); +var _reducer_wavelength = _interopRequireDefault(require("./reducer_wavelength")); +var _reducer_voltammetry = _interopRequireDefault(require("./reducer_voltammetry")); +var _reducer_curve = _interopRequireDefault(require("./reducer_curve")); +var _reducer_axes = _interopRequireDefault(require("./reducer_axes")); +var _reducer_detector = _interopRequireDefault(require("./reducer_detector")); +const rootReducer = (0, _redux.combineReducers)({ + threshold: _reducer_threshold.default, + editPeak: _reducer_edit_peak.default, + status: _reducer_status.default, + manager: _reducer_manager.default, + layout: _reducer_layout.default, + shift: _reducer_shift.default, + scan: _reducer_scan.default, + forecast: _reducer_forecast.default, + ui: _reducer_ui.default, + submit: _reducer_submit.default, + integration: _reducer_integration.default, + multiplicity: _reducer_multiplicity.default, + simulation: _reducer_simulation.default, + meta: _reducer_meta.default, + jcamp: _reducer_jcamp.default, + wavelength: _reducer_wavelength.default, + cyclicvolta: _reducer_voltammetry.default, + curve: _reducer_curve.default, + axesUnits: _reducer_axes.default, + detector: _reducer_detector.default +}); +var _default = exports.default = rootReducer; \ No newline at end of file diff --git a/dist/reducers/reducer_axes.js b/dist/reducers/reducer_axes.js new file mode 100644 index 00000000..889a70a7 --- /dev/null +++ b/dist/reducers/reducer_axes.js @@ -0,0 +1,59 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; +var _action_type = require("../constants/action_type"); +/* eslint-disable default-param-last, prefer-object-spread */ + +const initialState = { + axes: [{ + xUnit: '', + yUnit: '' + }] +}; +const updateAxis = function updateAxis(state, payload) { + let isYAxis = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; + const { + value, + curveIndex + } = payload; + const { + axes + } = state; + let selectedAxes = axes[curveIndex]; + if (!selectedAxes) { + selectedAxes = { + xUnit: '', + yUnit: '' + }; + } + let newAxes = null; + if (isYAxis) { + newAxes = Object.assign({}, selectedAxes, { + yUnit: value + }); + } else { + newAxes = Object.assign({}, selectedAxes, { + xUnit: value + }); + } + axes[curveIndex] = newAxes; + return Object.assign({}, state, { + axes + }); +}; +const axesReducer = function axesReducer() { + let state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : initialState; + let action = arguments.length > 1 ? arguments[1] : undefined; + switch (action.type) { + case _action_type.AXES.UPDATE_X_AXIS: + return updateAxis(state, action.payload); + case _action_type.AXES.UPDATE_Y_AXIS: + return updateAxis(state, action.payload, true); + default: + return state; + } +}; +var _default = exports.default = axesReducer; \ No newline at end of file diff --git a/dist/reducers/reducer_curve.js b/dist/reducers/reducer_curve.js new file mode 100644 index 00000000..0af10f6b --- /dev/null +++ b/dist/reducers/reducer_curve.js @@ -0,0 +1,82 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; +var _action_type = require("../constants/action_type"); +var _extractParams = require("../helpers/extractParams"); +var _chem = require("../helpers/chem"); +var _format = _interopRequireDefault(require("../helpers/format")); +/* eslint-disable prefer-object-spread, default-param-last, max-len */ + +const initialState = { + listCurves: [], + curveIdx: 0, + isShowAllCurve: false +}; +const setAllCurves = (state, action) => { + const { + payload + } = action; + if (payload) { + const entities = payload.map((entity, idx) => { + const { + topic, + feature, + hasEdit, + integration, + multiplicity + } = (0, _extractParams.extractParams)(entity, { + isEdit: true + }); + const simulation = entity && entity.features ? entity.features.simulation : undefined; + // const layout = entity.layout; + const { + layout + } = entity; + const maxminPeak = (0, _chem.Convert2MaxMinPeak)(layout, feature, 0); + const color = _format.default.mutiEntitiesColors(idx); + return { + layout, + topic, + feature, + hasEdit, + integration, + multiplicity, + simulation, + maxminPeak, + color, + curveIdx: idx + }; + }); + return Object.assign({}, state, { + curveIdx: 0, + listCurves: entities + }); + } + return Object.assign({}, state, { + curveIdx: 0, + listCurves: payload + }); +}; +const curveReducer = function curveReducer() { + let state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : initialState; + let action = arguments.length > 1 ? arguments[1] : undefined; + switch (action.type) { + case _action_type.CURVE.SELECT_WORKING_CURVE: + return Object.assign({}, state, { + curveIdx: action.payload + }); + case _action_type.CURVE.SET_ALL_CURVES: + return setAllCurves(state, action); + case _action_type.CURVE.SET_SHOULD_SHOW_ALL_CURVES: + return Object.assign({}, state, { + isShowAllCurve: action.payload + }); + default: + return state; + } +}; +var _default = exports.default = curveReducer; \ No newline at end of file diff --git a/dist/reducers/reducer_detector.js b/dist/reducers/reducer_detector.js new file mode 100644 index 00000000..8f0d76b3 --- /dev/null +++ b/dist/reducers/reducer_detector.js @@ -0,0 +1,52 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; +var _action_type = require("../constants/action_type"); +/* eslint-disable no-case-declarations */ +/* eslint-disable default-param-last */ + +const initialState = { + curves: [{ + curveIdx: 0, + selectedDetector: '' + }] +}; +const findCurveIndex = (curves, targetCurveIdx) => curves.findIndex(curve => curve.curveIdx === targetCurveIdx); +const updateOrAppendCurve = (curves, targetCurveIdx, newCurve) => { + const existingCurveIndex = findCurveIndex(curves, targetCurveIdx); + if (existingCurveIndex !== -1) { + return curves.map((curve, index) => index === existingCurveIndex ? { + ...curve, + ...newCurve + } : curve); + } + return [...curves, newCurve]; +}; +const detectorReducer = function detectorReducer() { + let state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : initialState; + let action = arguments.length > 1 ? arguments[1] : undefined; + switch (action.type) { + case _action_type.SEC.UPDATE_DETECTOR: + const { + curveIdx, + selectedDetector + } = action.payload; + // eslint-disable-next-line max-len + const updatedCurves = updateOrAppendCurve(state.curves, curveIdx, { + curveIdx, + selectedDetector + }); + return { + ...state, + curves: updatedCurves + }; + case _action_type.MANAGER.RESET_DETECTOR: + return initialState; + default: + return state; + } +}; +var _default = exports.default = detectorReducer; \ No newline at end of file diff --git a/dist/reducers/reducer_edit_peak.js b/dist/reducers/reducer_edit_peak.js new file mode 100644 index 00000000..f41f04a8 --- /dev/null +++ b/dist/reducers/reducer_edit_peak.js @@ -0,0 +1,235 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.editPeakReducer = exports.default = void 0; +var _reduxUndo = _interopRequireDefault(require("redux-undo")); +var _action_type = require("../constants/action_type"); +var _undo_redo_config = require("./undo_redo_config"); +var _calc = require("../helpers/calc"); +/* eslint-disable prefer-object-spread, default-param-last */ + +const initialState = { + selectedIdx: 0, + peaks: [{ + prevOffset: 0, + pos: [], + neg: [] + }] +}; +const defaultEmptyPeaks = { + prevOffset: 0, + pos: [], + neg: [] +}; +const addToPos = (state, action) => { + const { + peaks + } = state; + const { + payload + } = action; + const { + dataToAdd, + curveIdx + } = payload; + let selectedEditPeaks = peaks[curveIdx]; + if (!selectedEditPeaks) { + selectedEditPeaks = defaultEmptyPeaks; + } + const oriPosState = selectedEditPeaks.pos; + const oriNegState = selectedEditPeaks.neg; + const idxN = oriNegState.findIndex(n => (0, _calc.almostEqual)(n.x, dataToAdd.x)); + if (idxN >= 0) { + // rm the peak from oriNegState if it is already deleted. + const neg = [...oriNegState.slice(0, idxN), ...oriNegState.slice(idxN + 1)]; + const newSelectedEditPeaks = Object.assign({}, selectedEditPeaks, { + neg + }); + const newPeaks = [...peaks]; + newPeaks[curveIdx] = newSelectedEditPeaks; + return Object.assign({}, state, { + peaks: newPeaks + }); + } + const idxP = oriPosState.findIndex(p => (0, _calc.almostEqual)(p.x, dataToAdd.x)); + if (idxP < 0) { + // add the peak + const pos = [...oriPosState, dataToAdd]; + const newSelectedEditPeaks = Object.assign({}, selectedEditPeaks, { + pos + }); + const newPeaks = [...peaks]; + newPeaks[curveIdx] = newSelectedEditPeaks; + return Object.assign({}, state, { + peaks: newPeaks, + selectedIdx: curveIdx + }); + } + return state; +}; +const rmFromPos = (state, action) => { + const { + selectedIdx, + peaks + } = state; + const selectedEditPeaks = peaks[selectedIdx]; + const oriPosState = selectedEditPeaks.pos; + const idx = oriPosState.findIndex(p => p.x === action.payload.x); + const pos = [...oriPosState.slice(0, idx), ...oriPosState.slice(idx + 1)]; + const newSelectedEditPeaks = Object.assign({}, selectedEditPeaks, { + pos + }); + const newPeaks = [...peaks]; + newPeaks[selectedIdx] = newSelectedEditPeaks; + return Object.assign({}, state, { + peaks: newPeaks + }); +}; +const addToNeg = (state, action) => { + const { + peaks + } = state; + const { + payload + } = action; + const { + dataToAdd, + curveIdx + } = payload; + let selectedEditPeaks = peaks[curveIdx]; + if (!selectedEditPeaks) { + selectedEditPeaks = defaultEmptyPeaks; + } + const oriPosState = selectedEditPeaks.pos; + const oriNegState = selectedEditPeaks.neg; + const idxP = oriPosState.findIndex(n => n.x === dataToAdd.x); + if (idxP >= 0) { + const pos = [...oriPosState.slice(0, idxP), ...oriPosState.slice(idxP + 1)]; + const newSelectedEditPeaks = Object.assign({}, selectedEditPeaks, { + pos + }); + const newPeaks = [...peaks]; + newPeaks[curveIdx] = newSelectedEditPeaks; + return Object.assign({}, state, { + peaks: newPeaks + }); + } + const idxN = oriNegState.findIndex(n => n.x === dataToAdd.x); + if (idxN < 0) { + const neg = [...oriNegState, dataToAdd]; + const newSelectedEditPeaks = Object.assign({}, selectedEditPeaks, { + neg + }); + const newPeaks = [...peaks]; + newPeaks[curveIdx] = newSelectedEditPeaks; + return Object.assign({}, state, { + peaks: newPeaks, + selectedIdx: curveIdx + }); + } + return state; +}; +const rmFromNeg = (state, action) => { + const { + selectedIdx, + peaks + } = state; + const selectedEditPeaks = peaks[selectedIdx]; + const oriNegState = selectedEditPeaks.neg; + const idx = oriNegState.findIndex(n => n.x === action.payload.x); + const neg = [...oriNegState.slice(0, idx), ...oriNegState.slice(idx + 1)]; + const newSelectedEditPeaks = Object.assign({}, selectedEditPeaks, { + neg + }); + const newPeaks = [...peaks]; + newPeaks[selectedIdx] = newSelectedEditPeaks; + return Object.assign({}, state, { + peaks: newPeaks + }); +}; +const processShift = (state, action) => { + const { + payload + } = action; + const { + curveIdx + } = action.payload; + const { + peaks + } = state; + let selectedEditPeaks = peaks[curveIdx]; + if (!selectedEditPeaks) { + selectedEditPeaks = defaultEmptyPeaks; + } + const { + pos, + neg, + prevOffset + } = payload; + const newSelectedEditPeaks = Object.assign({}, selectedEditPeaks, { + pos, + neg, + prevOffset + }); + const newPeaks = [...peaks]; + newPeaks[curveIdx] = newSelectedEditPeaks; + return Object.assign({}, state, { + peaks: newPeaks + }); +}; +const clearAllPeaks = (state, action) => { + const { + curveIdx, + dataPeaks + } = action.payload; + const { + peaks + } = state; + const selectedEditPeaks = peaks[curveIdx]; + const { + pos + } = selectedEditPeaks; + const newSelectedEditPeaks = Object.assign({}, selectedEditPeaks, { + pos: [], + neg: [...pos, ...dataPeaks] + }); + const newPeaks = [...peaks]; + newPeaks[curveIdx] = newSelectedEditPeaks; + return Object.assign({}, state, { + peaks: newPeaks + }); +}; +const editPeakReducer = exports.editPeakReducer = function editPeakReducer() { + let state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : initialState; + let action = arguments.length > 1 ? arguments[1] : undefined; + switch (action.type) { + case _action_type.EDITPEAK.ADD_POSITIVE: + return addToPos(state, action); + case _action_type.EDITPEAK.ADD_NEGATIVE: + return addToNeg(state, action); + case _action_type.EDITPEAK.RM_POSITIVE: + return rmFromPos(state, action); + case _action_type.EDITPEAK.RM_NEGATIVE: + return rmFromNeg(state, action); + case _action_type.EDITPEAK.SHIFT: + return processShift(state, action); + case _action_type.EDITPEAK.CLEAR_ALL: + return clearAllPeaks(state, action); + case _action_type.MANAGER.RESETALL: + return { + selectedIdx: 0, + peaks: [{ + prevOffset: 0, + pos: [], + neg: [] + }] + }; + default: + return _undo_redo_config.undoRedoActions.indexOf(action.type) >= 0 ? Object.assign({}, state) : state; + } +}; +const undoableEditPeakReducer = (0, _reduxUndo.default)(editPeakReducer, _undo_redo_config.undoRedoConfig); +var _default = exports.default = undoableEditPeakReducer; \ No newline at end of file diff --git a/dist/reducers/reducer_forecast.js b/dist/reducers/reducer_forecast.js new file mode 100644 index 00000000..e78e8239 --- /dev/null +++ b/dist/reducers/reducer_forecast.js @@ -0,0 +1,161 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; +var _action_type = require("../constants/action_type"); +/* eslint-disable prefer-object-spread, default-param-last */ + +const initialState = { + predictions: { + outline: {}, + output: { + result: [] + } + }, + predictionsByCurve: {} +}; +const toCurveIdx = input => Number.isInteger(input) ? input : 0; +const getPredictionsByCurve = state => state.predictionsByCurve || {}; +const getPredictionsForCurve = (state, curveIdx) => getPredictionsByCurve(state)[curveIdx] || state.predictions; +const updateIrResl = (stResl, plPred) => { + const { + sma, + identity, + value + } = plPred; + const { + svgs + } = stResl; + const prevFgs = stResl.fgs; + const nextVal = { + [`status${identity}`]: value + }; + const nextFgs = prevFgs.map(fg => { + if (fg.sma === sma) { + return Object.assign({}, fg, nextVal); + } + return fg; + }); + const nextResult = { + type: 'ir', + fgs: nextFgs, + svgs + }; + return nextResult; +}; +const updateIrStatus = (state, action) => { + const { + predictions, + curveIdx + } = action.payload; + const targetIdx = toCurveIdx(curveIdx); + const targetPredictions = getPredictionsForCurve(state, targetIdx); + const { + outline, + output + } = targetPredictions; + const stResl = output.result[0]; + const nextResl = updateIrResl(stResl, predictions); + const nextPredictions = { + outline, + output: { + result: [nextResl] + } + }; + const predictionsByCurve = Object.assign({}, getPredictionsByCurve(state), { + [targetIdx]: nextPredictions + }); + return Object.assign({}, state, { + predictions: nextPredictions, + predictionsByCurve + }); +}; +const updateNmrResl = (stResl, plPred) => { + const { + idx, + atom, + identity, + value + } = plPred; + const preResult = stResl; + const nextShifts = preResult.shifts.map((s, index) => { + if (s.atom === atom && index === idx) { + return Object.assign({}, s, { + [`status${identity}`]: value + }); + } + return s; + }); + const nextResult = Object.assign({}, preResult, { + shifts: nextShifts + }); + return nextResult; +}; +const updateNmrStatus = (state, action) => { + const { + predictions, + curveIdx + } = action.payload; + const targetIdx = toCurveIdx(curveIdx); + const targetPredictions = getPredictionsForCurve(state, targetIdx); + const { + outline, + output + } = targetPredictions; + const stResl = output.result[0]; + const nextResl = updateNmrResl(stResl, predictions); + const nextPredictions = { + outline, + output: { + result: [nextResl] + } + }; + const predictionsByCurve = Object.assign({}, getPredictionsByCurve(state), { + [targetIdx]: nextPredictions + }); + return Object.assign({}, state, { + predictions: nextPredictions, + predictionsByCurve + }); +}; +const forecastReducer = function forecastReducer() { + let state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : initialState; + let action = arguments.length > 1 ? arguments[1] : undefined; + switch (action.type) { + case _action_type.FORECAST.INIT_STATUS: + if (!action.payload) return state; + { + const { + curveIdx, + ...payloadRest + } = action.payload; + const nextPredictions = payloadRest.predictions || state.predictions; + const nextState = Object.assign({}, state, payloadRest); + if (!Number.isInteger(curveIdx)) { + return nextState; + } + const predictionsByCurve = Object.assign({}, getPredictionsByCurve(state), nextPredictions ? { + [curveIdx]: nextPredictions + } : {}); + return Object.assign({}, nextState, { + predictionsByCurve + }); + } + case _action_type.FORECAST.SET_IR_STATUS: + return updateIrStatus(state, action); + case _action_type.FORECAST.SET_NMR_STATUS: + return updateNmrStatus(state, action); + case _action_type.FORECAST.CLEAR_STATUS: + return initialState; + case _action_type.MANAGER.RESETALL: + if (action.payload && action.payload.resetForecast) { + return initialState; + } + return state; + default: + return state; + } +}; +var _default = exports.default = forecastReducer; \ No newline at end of file diff --git a/dist/reducers/reducer_integration.js b/dist/reducers/reducer_integration.js new file mode 100644 index 00000000..50222bde --- /dev/null +++ b/dist/reducers/reducer_integration.js @@ -0,0 +1,236 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; +var _reduxUndo = _interopRequireDefault(require("redux-undo")); +var _action_type = require("../constants/action_type"); +var _integration = require("../helpers/integration"); +var _undo_redo_config = require("./undo_redo_config"); +/* eslint-disable prefer-object-spread, default-param-last */ + +const initialState = { + selectedIdx: 0, + integrations: [{ + stack: [], + refArea: 1, + refFactor: 1, + shift: 0, + edited: false + }] +}; +const defaultEmptyIntegration = { + stack: [], + refArea: 1, + refFactor: 1, + shift: 0, + edited: false +}; +const addToStack = (state, action) => { + const { + newData, + curveIdx + } = action.payload; + const { + integrations + } = state; + let selectedIntegration = integrations[curveIdx]; + if (selectedIntegration === false || selectedIntegration === undefined) { + selectedIntegration = defaultEmptyIntegration; + } + const { + stack, + refArea, + shift + } = selectedIntegration; + const { + xExtent, + data + } = newData; + const { + xL, + xU + } = xExtent; + if (!xL || !xU || xU - xL === 0) { + return state; + } + const area = (0, _integration.getArea)(xL, xU, data); + const defaultRefArea = stack.length === 0 ? area : refArea; + const absoluteArea = (0, _integration.getAbsoluteArea)(xL, xU, data); // area depends on y baseline + const newStack = [...stack, { + xL: xL + shift, + xU: xU + shift, + area, + absoluteArea + }]; + const newIntegration = Object.assign({}, selectedIntegration, { + stack: newStack, + refArea: defaultRefArea + }); + const newArrIntegration = [...integrations]; + newArrIntegration[curveIdx] = newIntegration; + return Object.assign({}, state, { + integrations: newArrIntegration, + selectedIdx: curveIdx + }); +}; +const rmFromStack = (state, action) => { + const { + dataToRemove, + curveIdx + } = action.payload; + const { + xL, + xU, + xExtent + } = dataToRemove; + const { + integrations + } = state; + const selectedIntegration = integrations[curveIdx]; + const { + stack + } = selectedIntegration; + let [txL, txU] = [0, 0]; + if (xL && xU) { + // rm click integration + [txL, txU] = [xL, xU]; + } else if (xExtent) { + // rm click multiplicity + [txL, txU] = [xExtent.xL, xExtent.xU]; + } else { + return state; + } + const newStack = stack.filter(k => k.xL !== txL && k.xU !== txU); + const newIntegration = Object.assign({}, selectedIntegration, { + stack: newStack + }); + const newArrIntegration = [...integrations]; + newArrIntegration[curveIdx] = newIntegration; + return Object.assign({}, state, { + integrations: newArrIntegration, + selectedIdx: curveIdx + }); +}; +const setRef = (state, action) => { + const { + refData, + curveIdx + } = action.payload; + const { + integrations + } = state; + const selectedIntegration = integrations[curveIdx]; + const { + stack + } = selectedIntegration; + const { + xL, + xU + } = refData; + const ref = stack.filter(k => k.xL === xL && k.xU === xU)[0]; + if (!ref) { + return state; + } + const refArea = ref.area; + const newIntegration = Object.assign({}, selectedIntegration, { + refArea + }); + const newArrIntegration = [...integrations]; + newArrIntegration[curveIdx] = newIntegration; + return Object.assign({}, state, { + integrations: newArrIntegration, + selectedIdx: curveIdx + }); +}; +const setFkr = (state, action) => { + const { + payload + } = action; + const { + curveIdx, + factor + } = payload; + const { + integrations + } = state; + const selectedIntegration = integrations[curveIdx]; + const val = parseFloat(factor); + const refFactor = val < 0.01 ? 0.01 : val; + const newIntegration = Object.assign({}, selectedIntegration, { + refFactor + }); + const newArrIntegration = [...integrations]; + newArrIntegration[curveIdx] = newIntegration; + return Object.assign({}, state, { + integrations: newArrIntegration + }); +}; +const setShift = (state, action) => { + const { + selectedIdx, + integrations + } = state; + const selectedIntegration = integrations[selectedIdx]; + const shift = action.payload.prevOffset; + const newIntegration = Object.assign({}, selectedIntegration, { + shift + }); + const newArrIntegration = [...integrations]; + newArrIntegration[selectedIdx] = newIntegration; + return Object.assign({}, state, { + integrations: newArrIntegration + }); +}; +const resetAll = (state, action) => { + const newState = action.payload; + return Object.assign({}, state, newState); +}; +const clearAll = (state, action) => { + const { + payload + } = action; + const { + curveIdx + } = payload; + const { + integrations + } = state; + const newIntegration = Object.assign({}, defaultEmptyIntegration, { + edited: true + }); + const newArrIntegration = [...integrations]; + newArrIntegration[curveIdx] = newIntegration; + return Object.assign({}, state, { + integrations: newArrIntegration, + selectedIdx: curveIdx + }); +}; +const integrationReducer = function integrationReducer() { + let state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : initialState; + let action = arguments.length > 1 ? arguments[1] : undefined; + switch (action.type) { + case _action_type.UI.SWEEP.SELECT_INTEGRATION: + return addToStack(state, action); + case _action_type.INTEGRATION.RM_ONE: + return rmFromStack(state, action); + case _action_type.INTEGRATION.SET_REF: + return setRef(state, action); + case _action_type.INTEGRATION.SET_FKR: + return setFkr(state, action); + case _action_type.INTEGRATION.RESET_ALL_RDC: + return resetAll(state, action); + case _action_type.INTEGRATION.CLEAR_ALL: + return clearAll(state, action); + case _action_type.EDITPEAK.SHIFT: + return setShift(state, action); + case _action_type.MANAGER.RESETALL: + return state; + default: + return _undo_redo_config.undoRedoActions.indexOf(action.type) >= 0 ? Object.assign({}, state) : state; + } +}; +const undoableIntegrationReducer = (0, _reduxUndo.default)(integrationReducer, _undo_redo_config.undoRedoConfig); +var _default = exports.default = undoableIntegrationReducer; \ No newline at end of file diff --git a/dist/reducers/reducer_jcamp.js b/dist/reducers/reducer_jcamp.js new file mode 100644 index 00000000..4c9c6154 --- /dev/null +++ b/dist/reducers/reducer_jcamp.js @@ -0,0 +1,102 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; +var _action_type = require("../constants/action_type"); +/* eslint-disable prefer-object-spread, default-param-last */ + +const initialState = { + selectedIdx: 0, + jcamps: [{ + others: [], + addOthersCb: false + }] +}; +const addOthers = (state, _ref) => { + let { + others, + addOthersCb + } = _ref; + const { + selectedIdx, + jcamps + } = state; + const selectedJcamp = jcamps[selectedIdx]; + if (selectedJcamp.others.length > 5) return state; + const decoOthers = others.map(o => Object.assign({}, o, { + show: true + })); + const newJcamp = Object.assign({}, selectedJcamp, { + others: [...decoOthers].slice(0, 5), + addOthersCb + }); + jcamps[selectedIdx] = newJcamp; + return Object.assign({}, state, { + jcamps + }); +}; +const rmOthersOne = (state, payload) => { + const { + selectedIdx, + jcamps + } = state; + const selectedJcamp = jcamps[selectedIdx]; + const idx = payload; + const { + others + } = selectedJcamp; + const nextOther = others.filter((_, i) => i !== idx); + const newJcamp = Object.assign({}, selectedJcamp, { + others: nextOther + }); + jcamps[selectedIdx] = newJcamp; + return Object.assign({}, state, { + jcamps + }); +}; +const toggleShow = (state, payload) => { + const { + selectedIdx, + jcamps + } = state; + const selectedJcamp = jcamps[selectedIdx]; + const idx = payload; + const { + others + } = selectedJcamp; + const nextOthers = others.map((o, i) => { + if (i !== idx) return o; + const currentShow = o.show; + return Object.assign({}, o, { + show: !currentShow + }); + }); + const newJcamp = Object.assign({}, selectedJcamp, { + others: nextOthers + }); + jcamps[selectedIdx] = newJcamp; + return Object.assign({}, state, { + jcamps + }); +}; +const layoutReducer = function layoutReducer() { + let state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : initialState; + let action = arguments.length > 1 ? arguments[1] : undefined; + switch (action.type) { + case _action_type.JCAMP.ADD_OTHERS: + return addOthers(state, action.payload); + case _action_type.JCAMP.RM_OTHERS_ONE: + return rmOthersOne(state, action.payload); + case _action_type.JCAMP.TOGGLE_SHOW: + return toggleShow(state, action.payload); + case _action_type.JCAMP.CLEAR_ALL: + return initialState; + case _action_type.MANAGER.RESETALL: + return initialState; + default: + return state; + } +}; +var _default = exports.default = layoutReducer; \ No newline at end of file diff --git a/dist/reducers/reducer_layout.js b/dist/reducers/reducer_layout.js new file mode 100644 index 00000000..c981d1c0 --- /dev/null +++ b/dist/reducers/reducer_layout.js @@ -0,0 +1,24 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; +var _action_type = require("../constants/action_type"); +var _list_layout = require("../constants/list_layout"); +/* eslint-disable prefer-object-spread, default-param-last */ + +const initialState = _list_layout.LIST_LAYOUT.C13; +const layoutReducer = function layoutReducer() { + let state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : initialState; + let action = arguments.length > 1 ? arguments[1] : undefined; + switch (action.type) { + case _action_type.LAYOUT.UPDATE: + return action.payload; + case _action_type.MANAGER.RESETALL: + return action.payload.operation.layout; + default: + return state; + } +}; +var _default = exports.default = layoutReducer; \ No newline at end of file diff --git a/dist/reducers/reducer_manager.js b/dist/reducers/reducer_manager.js new file mode 100644 index 00000000..bdeabc20 --- /dev/null +++ b/dist/reducers/reducer_manager.js @@ -0,0 +1,19 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; +/* eslint-disable prefer-object-spread, default-param-last */ +// import { MANAGER } from '../constants/action_type'; + +const initialState = {}; +const managerReducer = function managerReducer() { + let state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : initialState; + let action = arguments.length > 1 ? arguments[1] : undefined; + switch (action.type) { + default: + return state; + } +}; +var _default = exports.default = managerReducer; \ No newline at end of file diff --git a/dist/reducers/reducer_meta.js b/dist/reducers/reducer_meta.js new file mode 100644 index 00000000..7e1feca9 --- /dev/null +++ b/dist/reducers/reducer_meta.js @@ -0,0 +1,42 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; +var _action_type = require("../constants/action_type"); +/* eslint-disable prefer-object-spread, default-param-last */ + +const initialState = { + peaks: { + intervalL: null, + intervalR: null, + observeFrequency: null, + deltaX: null + }, + dscMetaData: { + meltingPoint: null, + tg: null + } +}; +const updateMetaData = (state, action) => { + const { + dscMetaData + } = action.payload; + return Object.assign({}, state, { + dscMetaData + }); +}; +const metaReducer = function metaReducer() { + let state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : initialState; + let action = arguments.length > 1 ? arguments[1] : undefined; + switch (action.type) { + case _action_type.META.UPDATE_PEAKS_RDC: + return Object.assign({}, state, action.payload); + case _action_type.META.UPDATE_META_DATA_RDC: + return updateMetaData(state, action); + default: + return state; + } +}; +var _default = exports.default = metaReducer; \ No newline at end of file diff --git a/dist/reducers/reducer_multiplicity.js b/dist/reducers/reducer_multiplicity.js new file mode 100644 index 00000000..3b070c3f --- /dev/null +++ b/dist/reducers/reducer_multiplicity.js @@ -0,0 +1,201 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; +var _reduxUndo = _interopRequireDefault(require("redux-undo")); +var _action_type = require("../constants/action_type"); +var _undo_redo_config = require("./undo_redo_config"); +/* eslint-disable prefer-object-spread, default-param-last */ + +const initialState = { + selectedIdx: 0, + multiplicities: [{ + stack: [], + shift: 0, + smExtext: false, + edited: false + }] +}; +const defaultEmptyMultiplicity = { + stack: [], + shift: 0, + smExtext: false, + edited: false +}; +const setShift = (state, action) => { + const shift = action.payload.prevOffset; + const { + selectedIdx, + multiplicities + } = state; + const selectedMulti = multiplicities[selectedIdx]; + const newSelectedMulti = Object.assign({}, selectedMulti, { + shift + }); + const newMultiplicities = [...multiplicities]; + newMultiplicities[selectedIdx] = newSelectedMulti; + return Object.assign({}, state, { + multiplicities: newMultiplicities + }); +}; +const rmFromStack = (state, action) => { + const { + dataToRemove, + curveIdx + } = action.payload; + const { + multiplicities + } = state; + const selectedMulti = multiplicities[curveIdx]; + const { + stack + } = selectedMulti; + const { + xL, + xU, + xExtent + } = dataToRemove; + let [txL, txU] = [0, 0]; + if (xL && xU) { + // rm click integration + [txL, txU] = [xL, xU]; + } else if (xExtent) { + // rm click multiplicity + [txL, txU] = [xExtent.xL, xExtent.xU]; + } else { + return state; + } + const newStack = stack.filter(k => { + const [kxL, kxU] = [k.xExtent.xL, k.xExtent.xU]; + return kxL !== txL && kxU !== txU; + }); + const newSmExtext = newStack[0] ? newStack[0].xExtent : false; + const newSelectedMulti = Object.assign({}, selectedMulti, { + stack: newStack, + smExtext: newSmExtext + }); + const newMultiplicities = [...multiplicities]; + newMultiplicities[curveIdx] = newSelectedMulti; + return Object.assign({}, state, { + multiplicities: newMultiplicities, + selectedIdx: curveIdx + }); +}; +const updateMpyJ = (state, action) => { + const { + payload + } = action; + const { + xExtent, + value + } = payload; + if (!value && value !== '') return state; + const { + selectedIdx, + multiplicities + } = state; + const selectedMulti = multiplicities[selectedIdx]; + const { + stack + } = selectedMulti; + const regx = /[^0-9.,-]/g; + const js = value.replace(regx, '').split(',').map(j => parseFloat(j)).filter(j => j); + const newStack = stack.map(k => { + if (k.xExtent.xL === xExtent.xL && k.xExtent.xU === xExtent.xU) { + if (k.mpyType === 'm') return Object.assign({}, k, { + js: [] + }); + return Object.assign({}, k, { + js + }); + } + return k; + }); + const newSelectedMulti = Object.assign({}, selectedMulti, { + stack: newStack + }); + const newMultiplicities = [...multiplicities]; + newMultiplicities[selectedIdx] = newSelectedMulti; + return Object.assign({}, state, { + multiplicities: newMultiplicities + }); +}; +const clickMpyOne = (state, action) => { + const { + payload + } = action; + const { + curveIdx, + payloadData + } = payload; + const { + multiplicities + } = state; + const selectedMulti = multiplicities[curveIdx]; + const newSelectedMulti = Object.assign({}, selectedMulti, { + smExtext: payloadData + }); + const newMultiplicities = [...multiplicities]; + newMultiplicities[curveIdx] = newSelectedMulti; + return Object.assign({}, state, { + multiplicities: newMultiplicities, + selectedIdx: curveIdx + }); +}; +const clearAll = (state, action) => { + const { + payload + } = action; + const { + curveIdx + } = payload; + const { + multiplicities + } = state; + const newSelectedMulti = Object.assign({}, defaultEmptyMultiplicity, { + edited: true + }); + const newMultiplicities = [...multiplicities]; + newMultiplicities[curveIdx] = newSelectedMulti; + return Object.assign({}, state, { + multiplicities: newMultiplicities + }); +}; +const multiplicityReducer = function multiplicityReducer() { + let state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : initialState; + let action = arguments.length > 1 ? arguments[1] : undefined; + switch (action.type) { + case _action_type.EDITPEAK.SHIFT: + return setShift(state, action); + case _action_type.INTEGRATION.RM_ONE: + return rmFromStack(state, action); + case _action_type.UI.SWEEP.SELECT_MULTIPLICITY_RDC: + case _action_type.MULTIPLICITY.PEAK_RM_BY_PANEL_RDC: + case _action_type.MULTIPLICITY.PEAK_RM_BY_UI_RDC: + case _action_type.MULTIPLICITY.PEAK_ADD_BY_UI_RDC: + case _action_type.MULTIPLICITY.RESET_ONE_RDC: + return action.payload; + case _action_type.MULTIPLICITY.UPDATE_J: + return updateMpyJ(state, action); + case _action_type.MULTIPLICITY.TYPE_SELECT_RDC: + return action.payload; + case _action_type.MULTIPLICITY.ONE_CLICK: + case _action_type.MULTIPLICITY.ONE_CLICK_BY_UI: + return clickMpyOne(state, action); + case _action_type.MULTIPLICITY.RESET_ALL_RDC: + return action.payload; + case _action_type.MULTIPLICITY.CLEAR_ALL: + return clearAll(state, action); + case _action_type.MANAGER.RESETALL: + return state; + case _action_type.MANAGER.RESET_MULTIPLICITY: + return initialState; + default: + return _undo_redo_config.undoRedoActions.indexOf(action.type) >= 0 ? Object.assign({}, state) : state; + } +}; +const undoableMultiplicityReducer = (0, _reduxUndo.default)(multiplicityReducer, _undo_redo_config.undoRedoConfig); +var _default = exports.default = undoableMultiplicityReducer; \ No newline at end of file diff --git a/dist/reducers/reducer_scan.js b/dist/reducers/reducer_scan.js new file mode 100644 index 00000000..34c03273 --- /dev/null +++ b/dist/reducers/reducer_scan.js @@ -0,0 +1,48 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; +var _action_type = require("../constants/action_type"); +/* eslint-disable prefer-object-spread, default-param-last */ + +const initialState = { + target: false, + count: 1, + isAuto: true +}; +const setTarget = (state, payload) => Object.assign({}, state, { + target: payload +}); +const resetAll = (state, payload) => { + const { + scanCount, + scanEditTarget + } = payload; + return Object.assign({}, state, { + target: false, + count: parseInt(scanCount, 10), + isAuto: !scanEditTarget + }); +}; +const toggleIsAuto = state => Object.assign({}, state, { + isAuto: !state.isAuto, + target: false +}); +const scanReducer = function scanReducer() { + let state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : initialState; + let action = arguments.length > 1 ? arguments[1] : undefined; + switch (action.type) { + case _action_type.SCAN.SET_TARGET: + case _action_type.SCAN.RESET_TARGET: + return setTarget(state, action.payload); + case _action_type.SCAN.TOGGLE_ISAUTO: + return toggleIsAuto(state); + case _action_type.MANAGER.RESET_INIT_MS: + return resetAll(state, action.payload); + default: + return state; + } +}; +var _default = exports.default = scanReducer; \ No newline at end of file diff --git a/dist/reducers/reducer_shift.js b/dist/reducers/reducer_shift.js new file mode 100644 index 00000000..a5b0fc7c --- /dev/null +++ b/dist/reducers/reducer_shift.js @@ -0,0 +1,245 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; +var _action_type = require("../constants/action_type"); +var _list_shift = require("../constants/list_shift"); +var _shift = require("../helpers/shift"); +/* eslint-disable prefer-object-spread, default-param-last */ + +const shiftNone = _list_shift.LIST_SHIFT_1H[0]; + +// const initialState = { +// ref: shiftNone, +// peak: false, +// enable: true, +// }; + +const initialState = { + selectedIdx: 0, + shifts: [{ + ref: shiftNone, + peak: false, + enable: true + }] +}; +const defaultEmptyShift = { + ref: shiftNone, + peak: false, + enable: true +}; +const resetRef = payload => { + const { + shift, + layout + } = payload; + if (!shift || !shift.solventName || !shift.solventValue) return shiftNone; + const name = shift.solventName; + let target = false; + const listShift = (0, _list_shift.getListShift)(layout); + listShift.forEach(l => { + if (l.name === name) { + target = l; + } + }); + return target || shiftNone[0]; +}; +const resetEnable = payload => { + const { + typ + } = payload.operation; + switch (typ) { + case 'NMR': + return true; + default: + return false; + } +}; +const resetShift = (state, action) => { + const { + payload + } = action; + const { + curvesInfo + } = payload; + const { + isMultiCurve, + curveIdx, + numberOfCurve + } = curvesInfo; + const { + shifts + } = state; + let selectedShift = shifts[curveIdx]; + if (selectedShift === false || selectedShift === undefined) { + selectedShift = defaultEmptyShift; + } + if (isMultiCurve) { + for (let idx = 0; idx < numberOfCurve; idx += 1) { + const checkShift = shifts[idx]; + if (!checkShift) { + shifts[idx] = defaultEmptyShift; + } + } + } + const newShift = Object.assign({}, defaultEmptyShift, { + ref: resetRef(payload), + enable: resetEnable(payload) + }); + shifts[curveIdx] = newShift; + return Object.assign({}, state, { + shifts, + selectedIdx: curveIdx + }); +}; +const updateShift = (state, action) => { + // eslint-disable-line + const { + selectedIdx, + shifts + } = state; + let selectedShift = shifts[selectedIdx]; + if (selectedShift === false || selectedShift === undefined) { + selectedShift = defaultEmptyShift; + } + const newShift = Object.assign({}, selectedShift, { + ref: false, + enable: selectedShift.enable + }); + shifts[selectedIdx] = newShift; + return Object.assign({}, state, { + shifts, + selectedIdx + }); +}; +const setRef = (state, action) => { + const { + payload + } = action; + const { + dataToSet, + curveIdx + } = payload; + const { + shifts + } = state; + let selectedShift = shifts[curveIdx]; + if (selectedShift === false || selectedShift === undefined) { + selectedShift = defaultEmptyShift; + } + const newShift = Object.assign({}, selectedShift, { + ref: dataToSet, + enable: true + }); + shifts[curveIdx] = newShift; + return Object.assign({}, state, { + shifts, + selectedIdx: curveIdx + }); +}; +const setPeak = (state, action) => { + const { + payload + } = action; + const { + dataToSet, + curveIdx + } = payload; + const { + shifts + } = state; + let selectedShift = shifts[curveIdx]; + if (selectedShift === false || selectedShift === undefined) { + selectedShift = defaultEmptyShift; + } + const resX = (0, _shift.CalcResidualX)(selectedShift.ref, selectedShift.peak, dataToSet); + const trueApex = (0, _shift.RealPts)([dataToSet], resX)[0]; + const isSamePt = selectedShift.peak.x === trueApex.x; + const truePeak = trueApex && trueApex.x && !isSamePt ? trueApex : false; + const newShift = Object.assign({}, selectedShift, { + peak: truePeak, + enable: true + }); + shifts[curveIdx] = newShift; + return Object.assign({}, state, { + shifts, + selectedIdx: curveIdx + }); +}; +const removePeak = (state, action) => { + // eslint-disable-line + const { + selectedIdx, + shifts + } = state; + let selectedShift = shifts[selectedIdx]; + if (selectedShift === false || selectedShift === undefined) { + selectedShift = defaultEmptyShift; + } + const newShift = Object.assign({}, selectedShift, { + peak: false, + enable: true + }); + shifts[selectedIdx] = newShift; + return Object.assign({}, state, { + shifts, + selectedIdx + }); +}; +const addNegative = (state, action) => { + const { + payload + } = action; + const { + dataToAdd, + curveIdx + } = payload; + const { + shifts + } = state; + let selectedShift = shifts[curveIdx]; + if (selectedShift === false || selectedShift === undefined) { + selectedShift = defaultEmptyShift; + } + const rmApex = selectedShift.peak.x === dataToAdd.x; + if (!rmApex) { + return state; + } + const newShift = Object.assign({}, selectedShift, { + peak: false, + enable: true + }); + shifts[curveIdx] = newShift; + return Object.assign({}, state, { + shifts, + selectedIdx: curveIdx + }); +}; +const shiftReducer = function shiftReducer() { + let state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : initialState; + let action = arguments.length > 1 ? arguments[1] : undefined; + switch (action.type) { + case _action_type.SHIFT.SET_REF: + return setRef(state, action); + case _action_type.SHIFT.SET_PEAK: + { + return setPeak(state, action); + } + case _action_type.SHIFT.RM_PEAK: + return removePeak(state, action); + case _action_type.EDITPEAK.ADD_NEGATIVE: + { + return addNegative(state, action); + } + case _action_type.LAYOUT.UPDATE: + return updateShift(initialState, action); + case _action_type.MANAGER.RESETSHIFT: + // case MANAGER.RESETALL: + return resetShift(initialState, action); + default: + return state; + } +}; +var _default = exports.default = shiftReducer; \ No newline at end of file diff --git a/dist/reducers/reducer_simulation.js b/dist/reducers/reducer_simulation.js new file mode 100644 index 00000000..0cd31f80 --- /dev/null +++ b/dist/reducers/reducer_simulation.js @@ -0,0 +1,27 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; +var _action_type = require("../constants/action_type"); +/* eslint-disable prefer-object-spread, default-param-last */ + +const initialState = { + nmrSimPeaks: [] +}; +const resetAll = (state, action) => { + const newState = action.payload; + return Object.assign({}, state, newState); +}; +const simulatioinReducer = function simulatioinReducer() { + let state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : initialState; + let action = arguments.length > 1 ? arguments[1] : undefined; + switch (action.type) { + case _action_type.SIMULATION.RESET_ALL_RDC: + return resetAll(state, action); + default: + return state; + } +}; +var _default = exports.default = simulatioinReducer; \ No newline at end of file diff --git a/dist/reducers/reducer_status.js b/dist/reducers/reducer_status.js new file mode 100644 index 00000000..53271517 --- /dev/null +++ b/dist/reducers/reducer_status.js @@ -0,0 +1,47 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; +var _action_type = require("../constants/action_type"); +/* eslint-disable prefer-object-spread, default-param-last */ + +const initialState = { + btnSubmit: false +}; +const statusReducer = function statusReducer() { + let state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : initialState; + let action = arguments.length > 1 ? arguments[1] : undefined; + switch (action.type) { + case _action_type.STATUS.TOGGLEBTNSUBMIT: + return Object.assign({}, state, { + btnSubmit: false + } // !state.btnSubmit + ); + case _action_type.STATUS.TOGGLEBTNALL: + return Object.assign({}, state, { + btnSubmit: false + } // !state.btnSubmit + ); + case _action_type.STATUS.ENABLEBTNALL: + case _action_type.EDITPEAK.ADDPOSITIVE: + case _action_type.EDITPEAK.RMPOSITIVE: + case _action_type.EDITPEAK.ADDNEGATIVE: + case _action_type.EDITPEAK.RMNEGATIVE: + case _action_type.THRESHOLD.UPDATE_VALUE: + case _action_type.THRESHOLD.RESET_VALUE: + return Object.assign({}, state, { + btnSubmit: false + }); + case _action_type.LAYOUT.UPDATE: + return Object.assign({}, state, { + btnSubmit: false + }); + case _action_type.MANAGER.RESETALL: + return initialState; + default: + return initialState; + } +}; +var _default = exports.default = statusReducer; \ No newline at end of file diff --git a/dist/reducers/reducer_submit.js b/dist/reducers/reducer_submit.js new file mode 100644 index 00000000..35dd2024 --- /dev/null +++ b/dist/reducers/reducer_submit.js @@ -0,0 +1,61 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; +var _action_type = require("../constants/action_type"); +var _format = _interopRequireDefault(require("../helpers/format")); +/* eslint-disable prefer-object-spread, default-param-last */ + +const initialState = { + isAscend: false, + isIntensity: true, + decimal: 2, + operation: { + name: 'empty' + } +}; +const updateOperation = action => ({ + operation: action.payload || initialState.operation +}); +const submitReducer = function submitReducer() { + let state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : initialState; + let action = arguments.length > 1 ? arguments[1] : undefined; + switch (action.type) { + case _action_type.SUBMIT.TOGGLE_IS_ASCEND: + return Object.assign({}, state, { + isAscend: !state.isAscend + }); + case _action_type.SUBMIT.TOGGLE_IS_INTENSITY: + return Object.assign({}, state, { + isIntensity: !state.isIntensity + }); + case _action_type.SUBMIT.UPDATE_OPERATION: + return Object.assign({}, state, updateOperation(action)); + case _action_type.SUBMIT.UPDATE_DECIMAL: + return Object.assign({}, state, { + decimal: action.payload.target.value + }); + case _action_type.LAYOUT.UPDATE: + { + const decimal = _format.default.spectraDigit(action.payload); + return Object.assign({}, state, { + decimal + }); + } + case _action_type.MANAGER.RESETALL: + { + const decimal = _format.default.spectraDigit(action.payload.operation.layout); + return Object.assign({}, state, { + decimal, + isIntensity: true, + isAscend: false + }); + } + default: + return state; + } +}; +var _default = exports.default = submitReducer; \ No newline at end of file diff --git a/dist/reducers/reducer_threshold.js b/dist/reducers/reducer_threshold.js new file mode 100644 index 00000000..3b35ae34 --- /dev/null +++ b/dist/reducers/reducer_threshold.js @@ -0,0 +1,224 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; +var _action_type = require("../constants/action_type"); +/* eslint-disable prefer-object-spread, default-param-last */ + +const initialState = { + selectedIdx: 0, + list: [{ + isEdit: true, + value: false, + upper: false, + lower: false + }] +}; + +// const defaultThresHold = { +// isEdit: true, +// value: false, +// upper: false, +// lower: false, +// }; + +const setThresHoldValue = (state, action) => { + const { + payload + } = action; + const { + list, + selectedIdx + } = state; + if (payload) { + const { + value, + curveIdx + } = payload; + const selectedThres = list[curveIdx]; + const newSelectedThres = Object.assign({}, selectedThres, { + value + }); + const newListThres = [...list]; + newListThres[curveIdx] = newSelectedThres; + return Object.assign({}, state, { + list: newListThres, + selectedIdx: curveIdx + }); + } + const selectedThres = list[selectedIdx]; + const newSelectedThres = Object.assign({}, selectedThres, { + value: payload + }); + const newListThres = [...list]; + newListThres[selectedIdx] = newSelectedThres; + return Object.assign({}, state, { + list: newListThres + }); +}; +const setThresHoldUpper = (state, action) => { + const { + payload + } = action; + const { + list, + selectedIdx + } = state; + if (payload) { + const { + value, + curveIdx + } = payload; + const selectedThres = list[curveIdx]; + const newSelectedThres = Object.assign({}, selectedThres, { + upper: value + }); + const newListThres = [...list]; + newListThres[curveIdx] = newSelectedThres; + return Object.assign({}, state, { + list: newListThres, + selectedIdx: curveIdx + }); + } + const selectedThres = list[selectedIdx]; + const newSelectedThres = Object.assign({}, selectedThres, { + upper: payload + }); + const newListThres = [...list]; + newListThres[selectedIdx] = newSelectedThres; + return Object.assign({}, state, { + list: newListThres + }); +}; +const setThresHoldLower = (state, action) => { + const { + payload + } = action; + const { + list, + selectedIdx + } = state; + if (payload) { + const { + value, + curveIdx + } = payload; + const selectedThres = list[curveIdx]; + const newSelectedThres = Object.assign({}, selectedThres, { + lower: value + }); + const newListThres = [...list]; + newListThres[curveIdx] = newSelectedThres; + return Object.assign({}, state, { + list: newListThres, + selectedIdx: curveIdx + }); + } + const selectedThres = list[selectedIdx]; + const newSelectedThres = Object.assign({}, selectedThres, { + lower: payload + }); + const newListThres = [...list]; + newListThres[selectedIdx] = newSelectedThres; + return Object.assign({}, state, { + list: newListThres + }); +}; +const setThresHoldIsEdit = state => { + const { + list, + selectedIdx + } = state; + const selectedThres = list[selectedIdx]; + const { + isEdit + } = selectedThres; + const newSelectedThres = Object.assign({}, selectedThres, { + isEdit: !isEdit + }); + const newListThres = [...list]; + newListThres[selectedIdx] = newSelectedThres; + return Object.assign({}, state, { + list: newListThres + }); +}; +const resetAll = (state, action) => { + const { + payload + } = action; + const { + list + } = state; + const newList = list.map(item => ({ + isEdit: item.isEdit, + value: payload && payload.thresRef, + upper: item.upper, + lower: item.lower + })); + return Object.assign({}, state, { + selectedIdx: 0, + list: newList + }); +}; +const setListThreshold = (state, action) => { + const { + payload + } = action; + const { + list + } = state; + if (payload && payload.length > list.length) { + const newList = payload.map(() => ({ + isEdit: true, + value: false, + upper: false, + lower: false + })); + return Object.assign({}, state, { + list: newList + }); + } + return state; +}; +const resetInitCommon = state => { + const { + list + } = state; + const newList = list.map(item => ({ + isEdit: true, + value: item.value, + upper: item.upper, + lower: item.lower + })); + return Object.assign({}, state, { + selectedIdx: 0, + list: newList + }); +}; +const thresholdReducer = function thresholdReducer() { + let state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : initialState; + let action = arguments.length > 1 ? arguments[1] : undefined; + switch (action.type) { + case _action_type.CURVE.SET_ALL_CURVES: + return setListThreshold(state, action); + case _action_type.THRESHOLD.UPDATE_VALUE: + return setThresHoldValue(state, action); + case _action_type.THRESHOLD.UPDATE_UPPER_VALUE: + return setThresHoldUpper(state, action); + case _action_type.THRESHOLD.UPDATE_LOWER_VALUE: + return setThresHoldLower(state, action); + case _action_type.THRESHOLD.RESET_VALUE: + return setThresHoldValue(state, action); + case _action_type.THRESHOLD.TOGGLE_ISEDIT: + return setThresHoldIsEdit(state); + case _action_type.MANAGER.RESET_INIT_COMMON: + return resetInitCommon(state); + case _action_type.MANAGER.RESETALL: + return resetAll(state, action); + default: + return state; + } +}; +var _default = exports.default = thresholdReducer; \ No newline at end of file diff --git a/dist/reducers/reducer_ui.js b/dist/reducers/reducer_ui.js new file mode 100644 index 00000000..206b8212 --- /dev/null +++ b/dist/reducers/reducer_ui.js @@ -0,0 +1,51 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; +var _action_type = require("../constants/action_type"); +var _list_ui = require("../constants/list_ui"); +/* eslint-disable prefer-object-spread, default-param-last */ + +const initialState = { + viewer: _list_ui.LIST_UI_VIEWER_TYPE.SPECTRUM, + sweepType: _list_ui.LIST_UI_SWEEP_TYPE.ZOOMIN, + sweepExtent: { + xExtent: false, + yExtent: false + }, + jcampIdx: 0 +}; +const uiReducer = function uiReducer() { + let state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : initialState; + let action = arguments.length > 1 ? arguments[1] : undefined; + switch (action.type) { + case _action_type.UI.VIEWER.SET_TYPE: + return Object.assign({}, state, { + viewer: action.payload + }); + case _action_type.UI.SWEEP.SET_TYPE: + if (action.payload === _list_ui.LIST_UI_SWEEP_TYPE.ZOOMRESET) { + return Object.assign({}, state, { + sweepExtent: { + xExtent: false, + yExtent: false + } + }); + } + return Object.assign({}, state, { + sweepType: action.payload, + jcampIdx: action.jcampIdx + }); + case _action_type.UI.SWEEP.SELECT_ZOOMIN: + return Object.assign({}, state, { + sweepExtent: action.payload + }); + case _action_type.MANAGER.RESETALL: + return initialState; + default: + return state; + } +}; +var _default = exports.default = uiReducer; \ No newline at end of file diff --git a/dist/reducers/reducer_voltammetry.js b/dist/reducers/reducer_voltammetry.js new file mode 100644 index 00000000..3bc1f83c --- /dev/null +++ b/dist/reducers/reducer_voltammetry.js @@ -0,0 +1,574 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; +var _action_type = require("../constants/action_type"); +var _chem = require("../helpers/chem"); +/* eslint-disable prefer-object-spread, default-param-last */ + +const initialState = { + spectraList: [] +}; +const initSpectra = { + list: [], + origin: [], + selectedIdx: -1, + isWorkMaxPeak: true, + jcampIdx: -1, + shift: { + ref: null, + val: 0, + prevValue: 0 + }, + hasRefPeak: false, + history: [] +}; +const addPairPeak = (state, action) => { + const { + payload + } = action; + const { + spectraList + } = state; + if (payload !== undefined) { + let spectra = spectraList[payload]; + if (!spectra) { + spectra = initSpectra; + spectraList.push(spectra); + } + const { + list, + selectedIdx + } = spectra; + let index = selectedIdx; + index += 1; + const newList = list.map(item => { + // eslint-disable-line + return { + ...item + }; + }); + newList.push({ + min: null, + max: null, + isRef: false, + e12: null, + createdAt: Date.now() + }); + spectraList[payload] = Object.assign({}, spectra, { + list: newList, + selectedIdx: index, + origin: [...newList] + }); // eslint-disable-line + return Object.assign({}, state, { + spectraList + }); + } + return state; +}; +const removePairPeak = (state, action) => { + const { + payload + } = action; + const { + spectraList + } = state; + if (payload !== undefined) { + const { + index, + jcampIdx + } = payload; + const spectra = spectraList[jcampIdx]; + if (spectra) { + const { + list, + origin + } = spectra; + list.splice(index, 1); + origin.splice(index, 1); + spectraList[jcampIdx] = Object.assign({}, spectra, { + list, + selectedIdx: index, + origin + }); + return Object.assign({}, state, { + spectraList + }); + } + return state; + } + return state; +}; +const getE12 = data => { + if (data.max && data.min) { + const { + max, + min + } = data; + const delta = (0, _chem.GetCyclicVoltaPeakSeparate)(max.x, min.x); + return Math.min(max.x, min.x) + 0.5 * delta; + } + return null; +}; +const addPeak = function addPeak(state, action) { + let isMax = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true; + const { + payload + } = action; + const { + spectraList + } = state; + if (payload) { + const { + peak, + index, + jcampIdx + } = payload; + const spectra = spectraList[jcampIdx]; + const { + list + } = spectra; + const newList = list.map(item => { + // eslint-disable-line + return { + ...item + }; + }); + let pairPeak = newList[index]; + if (isMax) { + pairPeak = Object.assign({}, pairPeak, { + max: peak + }); + } else { + pairPeak = Object.assign({}, pairPeak, { + min: peak + }); + } + pairPeak.e12 = getE12(pairPeak); + pairPeak.updatedAt = Date.now(); + newList[index] = pairPeak; + spectraList[jcampIdx] = Object.assign({}, spectra, { + list: newList, + selectedIdx: index, + jcampIdx, + origin: [...newList] + }); + return Object.assign({}, state, { + spectraList + }); + } + return state; +}; +const removePeak = function removePeak(state, action) { + let isMax = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true; + const { + payload + } = action; + const { + spectraList + } = state; + if (payload) { + const { + index, + jcampIdx + } = payload; + const spectra = spectraList[jcampIdx]; + const { + list + } = spectra; + const newList = list; + const pairPeak = newList[index]; + if (isMax) { + pairPeak.max = null; + } else { + pairPeak.min = null; + } + pairPeak.e12 = getE12(pairPeak); + pairPeak.updatedAt = Date.now(); + newList[index] = pairPeak; + spectraList[jcampIdx] = Object.assign({}, spectra, { + list: newList, + selectedIdx: index, + jcampIdx, + origin: [...newList] + }); + return Object.assign({}, state, { + spectraList + }); + } + return state; +}; +const selectPairPeak = (state, action) => { + const { + payload + } = action; + if (payload !== undefined) { + const { + spectraList + } = state; + const { + index, + jcampIdx + } = payload; + const spectra = spectraList[jcampIdx]; + if (spectra) { + spectraList[jcampIdx] = Object.assign({}, spectra, { + selectedIdx: index + }); + return Object.assign({}, state, { + spectraList + }); + } + return state; + } + return state; +}; +const setWorkWithMaxPeak = (state, action) => { + const { + payload + } = action; + if (payload !== undefined) { + const { + spectraList + } = state; + const { + isMax, + jcampIdx + } = payload; + const spectra = spectraList[jcampIdx]; + if (spectra) { + spectraList[jcampIdx] = Object.assign({}, spectra, { + isWorkMaxPeak: isMax + }); + return Object.assign({}, state, { + spectraList + }); + } + return state; + } + return state; +}; +const addPecker = (state, action) => { + const { + payload + } = action; + const { + spectraList + } = state; + if (payload) { + const { + peak, + index, + jcampIdx + } = payload; + const spectra = spectraList[jcampIdx]; + const { + list + } = spectra; + const newList = list; + const pairPeak = newList[index]; + pairPeak.pecker = peak; + pairPeak.updatedAt = Date.now(); + newList[index] = pairPeak; + spectraList[jcampIdx] = Object.assign({}, spectra, { + list: newList, + selectedIdx: index, + jcampIdx, + origin: [...newList] + }); + return Object.assign({}, state, { + spectraList + }); + } + return state; +}; +const removePecker = (state, action) => { + const { + payload + } = action; + const { + spectraList + } = state; + if (payload) { + const { + index, + jcampIdx + } = payload; + const spectra = spectraList[jcampIdx]; + const { + list + } = spectra; + const newList = list; + const pairPeak = newList[index]; + pairPeak.pecker = null; + pairPeak.updatedAt = Date.now(); + newList[index] = pairPeak; + spectraList[jcampIdx] = Object.assign({}, spectra, { + list: newList, + selectedIdx: index, + jcampIdx, + origin: [...newList] + }); + return Object.assign({}, state, { + spectraList + }); + } + return state; +}; +const setRef = (state, action) => { + const { + payload + } = action; + const { + spectraList + } = state; + if (payload) { + const { + jcampIdx + } = payload; + const spectra = spectraList[jcampIdx]; + const { + list, + shift, + hasRefPeak, + history + } = spectra; + const newShift = Object.assign({}, shift); + const refPeaks = list.filter(pairPeak => pairPeak.isRef === true); + let offset = 0.0; + if (hasRefPeak) { + const currRefPeaks = refPeaks[0]; + newShift.ref = currRefPeaks; + const { + val + } = shift; + const { + e12 + } = currRefPeaks; + offset = e12 - val; + const newList = spectra.list.map(pairPeak => { + //eslint-disable-line + const { + max, + min, + pecker, + isRef + } = pairPeak; + let newMax = null; + let newMin = null; + let newPecker = null; + if (max) { + newMax = hasRefPeak ? { + x: max.x - offset, + y: max.y + } : { + x: max.x + parseFloat(offset), + y: max.y + }; + } + if (min) { + newMin = hasRefPeak ? { + x: min.x - offset, + y: min.y + } : { + x: min.x + parseFloat(offset), + y: min.y + }; + } + if (pecker) { + newPecker = hasRefPeak ? { + x: pecker.x - offset, + y: pecker.y + } : { + x: pecker.x + parseFloat(offset), + y: pecker.y + }; //eslint-disable-line + } + const newPairPeak = Object.assign({}, pairPeak, { + max: newMax, + min: newMin, + pecker: newPecker + }); //eslint-disable-line + newPairPeak.e12 = getE12(newPairPeak); + newPairPeak.updatedAt = Date.now(); + if (isRef) { + newShift.ref = newPairPeak; + newShift.prevValue += offset; + } + return newPairPeak; + }); + history.push(...[newList]); + spectra.list = newList; + } else { + newShift.ref = null; + const { + val + } = newShift; + offset = val; + const newList = spectra.origin.map(pairPeak => { + //eslint-disable-line + const { + max, + min, + pecker + } = pairPeak; + let newMax = null; + let newMin = null; + let newPecker = null; + if (max) { + newMax = { + x: max.x + parseFloat(val), + y: max.y + }; + } + if (min) { + newMin = { + x: min.x + parseFloat(val), + y: min.y + }; + } + if (pecker) { + newPecker = { + x: pecker.x + parseFloat(val), + y: pecker.y + }; + } + const newPairPeak = Object.assign({}, pairPeak, { + max: newMax, + min: newMin, + pecker: newPecker, + isRef: false + }); //eslint-disable-line + newPairPeak.e12 = getE12(newPairPeak); + newPairPeak.updatedAt = Date.now(); + return newPairPeak; + }); + history.push(...[newList]); + spectra.list = newList; + newShift.prevValue = parseFloat(offset); + } + spectraList[jcampIdx] = Object.assign({}, spectra, { + shift: newShift, + jcampIdx + }); + return Object.assign({}, state, { + spectraList + }); + } + return state; +}; +const selectRefPeaks = (state, action) => { + const { + payload + } = action; + const { + spectraList + } = state; + if (payload) { + const { + index, + jcampIdx, + checked + } = payload; + const spectra = spectraList[jcampIdx]; + const { + list, + shift, + history + } = spectra; + const newShift = shift; + const newList = list; + newList.forEach((pairPeak, idx) => { + const newPairPeak = pairPeak; + newPairPeak.isRef = false; + newPairPeak.updatedAt = Date.now(); + if (idx === index) { + newPairPeak.isRef = checked; + newList[index] = newPairPeak; + } + }); + const refPeaks = newList.filter(pairPeak => pairPeak.isRef === true); + const hasRefPeak = refPeaks.length > 0; + history.push(...[newList]); + spectraList[jcampIdx] = Object.assign({}, spectra, { + list: newList, + selectedIdx: index, + jcampIdx, + hasRefPeak, + shift: newShift + }); + return Object.assign({}, state, { + spectraList + }); + } + return state; +}; +const selectRefFactor = (state, action) => { + const { + payload + } = action; + const { + spectraList + } = state; + if (payload) { + const { + factor, + curveIdx + } = payload; + const spectra = spectraList[curveIdx]; + const { + shift + } = spectra; + const newShift = Object.assign({}, shift); + newShift.val = factor; + spectraList[curveIdx] = Object.assign({}, spectra, { + shift: newShift, + jcampIdx: curveIdx + }); + return Object.assign({}, state, { + spectraList + }); + } + return state; +}; +const cyclicVoltaReducer = function cyclicVoltaReducer() { + let state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : initialState; + let action = arguments.length > 1 ? arguments[1] : undefined; + switch (action.type) { + case _action_type.CYCLIC_VOLTA_METRY.ADD_PAIR_PEAKS: + return addPairPeak(state, action); + case _action_type.CYCLIC_VOLTA_METRY.REMOVE_PAIR_PEAKS: + return removePairPeak(state, action); + case _action_type.CYCLIC_VOLTA_METRY.ADD_MAX_PEAK: + return addPeak(state, action); + case _action_type.CYCLIC_VOLTA_METRY.REMOVE_MAX_PEAK: + return removePeak(state, action); + case _action_type.CYCLIC_VOLTA_METRY.ADD_MIN_PEAK: + return addPeak(state, action, false); + case _action_type.CYCLIC_VOLTA_METRY.REMOVE_MIN_PEAK: + return removePeak(state, action, false); + case _action_type.CYCLIC_VOLTA_METRY.WORK_WITH_MAX_PEAK: + return setWorkWithMaxPeak(state, action); + case _action_type.CYCLIC_VOLTA_METRY.SELECT_PAIR_PEAK: + return selectPairPeak(state, action); + case _action_type.CYCLIC_VOLTA_METRY.ADD_PECKER: + return addPecker(state, action); + case _action_type.CYCLIC_VOLTA_METRY.REMOVE_PECKER: + return removePecker(state, action); + case _action_type.CYCLIC_VOLTA_METRY.SET_REF: + return setRef(state, action); + case _action_type.CYCLIC_VOLTA_METRY.SELECT_REF_PEAK: + return selectRefPeaks(state, action); + case _action_type.CYCLIC_VOLTA_METRY.SET_FACTOR: + return selectRefFactor(state, action); + case _action_type.CYCLIC_VOLTA_METRY.RESETALL: + return Object.assign({}, state, { + spectraList: [] + }); + default: + return state; + } +}; +var _default = exports.default = cyclicVoltaReducer; \ No newline at end of file diff --git a/dist/reducers/reducer_wavelength.js b/dist/reducers/reducer_wavelength.js new file mode 100644 index 00000000..8c3dfea9 --- /dev/null +++ b/dist/reducers/reducer_wavelength.js @@ -0,0 +1,22 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; +var _list_wavelength = require("../constants/list_wavelength"); +var _action_type = require("../constants/action_type"); +/* eslint-disable default-param-last */ + +const initialState = _list_wavelength.LIST_WAVE_LENGTH[0]; +const wavelengthReducer = function wavelengthReducer() { + let state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : initialState; + let action = arguments.length > 1 ? arguments[1] : undefined; + switch (action.type) { + case _action_type.XRD.UPDATE_WAVE_LENGTH: + return action.payload; + default: + return state; + } +}; +var _default = exports.default = wavelengthReducer; \ No newline at end of file diff --git a/dist/reducers/undo_redo_config.js b/dist/reducers/undo_redo_config.js new file mode 100644 index 00000000..7a8cfeaa --- /dev/null +++ b/dist/reducers/undo_redo_config.js @@ -0,0 +1,17 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.undoRedoConfig = exports.undoRedoActions = void 0; +var _reduxUndo = require("redux-undo"); +var _action_type = require("../constants/action_type"); +const undoRedoActions = exports.undoRedoActions = [_action_type.EDITPEAK.ADD_POSITIVE, _action_type.EDITPEAK.ADD_NEGATIVE, _action_type.EDITPEAK.RM_POSITIVE, _action_type.EDITPEAK.RM_NEGATIVE, _action_type.EDITPEAK.SHIFT, _action_type.EDITPEAK.CLEAR_ALL, _action_type.MANAGER.RESETALL, _action_type.MANAGER.RESETSHIFT, _action_type.MANAGER.RESET_INIT_COMMON, _action_type.MANAGER.RESET_INIT_NMR, _action_type.MANAGER.RESET_INIT_MS, _action_type.MANAGER.RESET_INIT_COMMON_WITH_INTERGATION, _action_type.UI.SWEEP.SELECT_INTEGRATION, _action_type.UI.SWEEP.SELECT_MULTIPLICITY_RDC, _action_type.INTEGRATION.RM_ONE, _action_type.INTEGRATION.SET_REF, _action_type.INTEGRATION.SET_FKR, _action_type.INTEGRATION.RESET_ALL, _action_type.INTEGRATION.CLEAR_ALL, _action_type.MULTIPLICITY.PEAK_RM_BY_PANEL_RDC, _action_type.MULTIPLICITY.PEAK_RM_BY_UI_RDC, _action_type.MULTIPLICITY.PEAK_ADD_BY_UI_RDC, _action_type.MULTIPLICITY.RESET_ONE_RDC, _action_type.MULTIPLICITY.UPDATE_J, _action_type.MULTIPLICITY.TYPE_SELECT_RDC, _action_type.MULTIPLICITY.ONE_CLICK, _action_type.MULTIPLICITY.ONE_CLICK_BY_UI, _action_type.MULTIPLICITY.RESET_ALL_RDC, _action_type.MULTIPLICITY.CLEAR_ALL]; +const undoRedoConfig = exports.undoRedoConfig = { + debug: false, + limit: 10, + ignoreInitialState: true, + filter: (0, _reduxUndo.includeAction)(undoRedoActions), + clearHistoryType: [_action_type.EDITPEAK.SHIFT, _action_type.EDITPEAK.CLEAR_ALL, _action_type.MANAGER.RESETALL, _action_type.MANAGER.RESETSHIFT, _action_type.MANAGER.RESET_INIT_COMMON, _action_type.MANAGER.RESET_INIT_NMR, _action_type.MANAGER.RESET_INIT_MS, _action_type.MANAGER.RESET_INIT_COMMON_WITH_INTERGATION], + neverSkipReducer: [_action_type.EDITPEAK.SHIFT, _action_type.EDITPEAK.CLEAR_ALL, _action_type.MANAGER.RESETALL, _action_type.MANAGER.RESETSHIFT, _action_type.MANAGER.RESET_INIT_COMMON, _action_type.MANAGER.RESET_INIT_NMR, _action_type.MANAGER.RESET_INIT_MS, _action_type.MANAGER.RESET_INIT_COMMON_WITH_INTERGATION] +}; \ No newline at end of file diff --git a/dist/sagas/index.js b/dist/sagas/index.js new file mode 100644 index 00000000..6b9c1884 --- /dev/null +++ b/dist/sagas/index.js @@ -0,0 +1,17 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = rootSaga; +var _effects = require("redux-saga/effects"); +var _saga_edit_peak = _interopRequireDefault(require("./saga_edit_peak")); +var _saga_manager = _interopRequireDefault(require("./saga_manager")); +var _saga_ui = _interopRequireDefault(require("./saga_ui")); +var _saga_meta = _interopRequireDefault(require("./saga_meta")); +var _saga_multiplicity = _interopRequireDefault(require("./saga_multiplicity")); +var _saga_multi_entities = _interopRequireDefault(require("./saga_multi_entities")); +function* rootSaga() { + yield (0, _effects.all)([..._saga_edit_peak.default, ..._saga_manager.default, ..._saga_ui.default, ..._saga_meta.default, ..._saga_multiplicity.default, ..._saga_multi_entities.default]); +} \ No newline at end of file diff --git a/dist/sagas/saga_edit_peak.js b/dist/sagas/saga_edit_peak.js new file mode 100644 index 00000000..a68ad59d --- /dev/null +++ b/dist/sagas/saga_edit_peak.js @@ -0,0 +1,75 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; +var _effects = require("redux-saga/effects"); +var _action_type = require("../constants/action_type"); +var _shift = require("../helpers/shift"); +var _list_shift = require("../constants/list_shift"); +const getShift = state => state.shift; +const getEditPeak = state => state.editPeak.present; +function* addVirtualFactor(action) { + const originShift = yield (0, _effects.select)(getShift); + const origEPeak = yield (0, _effects.select)(getEditPeak); + const { + payload + } = action; + const { + curveIdx + } = payload; + const { + peaks + } = origEPeak; + let currentOriginPeaks = peaks[curveIdx]; + if (currentOriginPeaks === false || currentOriginPeaks === undefined) { + currentOriginPeaks = { + prevOffset: 0, + pos: [], + neg: [] + }; + } + let currentOriginShift = originShift.shifts[curveIdx]; + if (currentOriginShift === false || currentOriginShift === undefined) { + const shiftNone = _list_shift.LIST_SHIFT_1H[0]; + currentOriginShift = { + ref: shiftNone, + peak: false, + enable: true + }; + } + const origRef = currentOriginShift.ref; + const origApex = currentOriginShift.peak; + const { + prevOffset, + pos, + neg + } = currentOriginPeaks; + const absOffset = (0, _shift.FromManualToOffset)(origRef, origApex); + const relOffset = prevOffset - absOffset; + const nextPos = (0, _shift.VirtalPts)(pos, relOffset); + const nextNeg = (0, _shift.VirtalPts)(neg, relOffset); + yield (0, _effects.put)({ + type: _action_type.EDITPEAK.SHIFT, + payload: Object.assign({}, payload, { + // eslint-disable-line + prevOffset: absOffset, + pos: nextPos, + neg: nextNeg + }) + }); +} +const editPeakSagas = [(0, _effects.takeEvery)(_action_type.SHIFT.SET_REF, addVirtualFactor), (0, _effects.takeEvery)(_action_type.SHIFT.SET_PEAK, addVirtualFactor)]; +var _default = exports.default = editPeakSagas; +/* LOGIC + -no po - tg + | picked | another | absoffset | prevOffset | relative | newOffset +------------------------------------------------------------------- +0 | 40 20 - - - 0 +1 | 180 160 -140 0 140 140 +2 | 80 60 -40 -140 -100 100 +3 | 20 0 +20 -100 -120 +------------------------------------------------------------------- + +*/ \ No newline at end of file diff --git a/dist/sagas/saga_manager.js b/dist/sagas/saga_manager.js new file mode 100644 index 00000000..e87aec57 --- /dev/null +++ b/dist/sagas/saga_manager.js @@ -0,0 +1,97 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; +var _effects = require("redux-saga/effects"); +var _action_type = require("../constants/action_type"); +const getLayout = state => state.layout; +const getCurveSt = state => state.curve; +const getIntegrationSt = state => state.integration.present; +function* resetShift(action) { + const curveSt = yield (0, _effects.select)(getCurveSt); + const layout = yield (0, _effects.select)(getLayout); + const { + payload + } = action; + const { + curveIdx, + listCurves + } = curveSt; + const numberOfCurve = listCurves.length; + yield (0, _effects.put)({ + type: _action_type.MANAGER.RESETSHIFT, + payload: Object.assign( + // eslint-disable-line + {}, payload, { + layout, + curvesInfo: { + isMultiCurve: numberOfCurve > 0, + curveIdx, + numberOfCurve + } + }) + }); +} +function* resetInitNmr(action) { + const curveSt = yield (0, _effects.select)(getCurveSt); + const integationSt = yield (0, _effects.select)(getIntegrationSt); + const { + curveIdx + } = curveSt; + const { + integration, + simulation + } = action.payload; + const { + integrations + } = integationSt; + const newArrIntegration = [...integrations]; + newArrIntegration[curveIdx] = integration; + const payload = Object.assign({}, integationSt, { + integrations: newArrIntegration, + selectedIdx: curveIdx + }); // eslint-disable-line + + if (integration) { + yield (0, _effects.put)({ + type: _action_type.INTEGRATION.RESET_ALL_RDC, + payload + }); + } + if (simulation) { + yield (0, _effects.put)({ + type: _action_type.SIMULATION.RESET_ALL_RDC, + payload: simulation + }); + } +} +function* resetInitCommonWithIntergation(action) { + const curveSt = yield (0, _effects.select)(getCurveSt); + const integationSt = yield (0, _effects.select)(getIntegrationSt); + const { + curveIdx + } = curveSt; + const { + integration + } = action.payload; + const { + integrations + } = integationSt; + const newArrIntegration = [...integrations]; + newArrIntegration[curveIdx] = integration; + const payload = Object.assign({}, integationSt, { + integrations: newArrIntegration, + selectedIdx: curveIdx + }); // eslint-disable-line + + if (integration) { + yield (0, _effects.put)({ + type: _action_type.INTEGRATION.RESET_ALL_RDC, + payload + }); + } +} +const managerSagas = [(0, _effects.takeEvery)(_action_type.MANAGER.RESETALL, resetShift), (0, _effects.takeEvery)(_action_type.MANAGER.RESET_INIT_NMR, resetInitNmr), (0, _effects.takeEvery)(_action_type.MANAGER.RESET_INIT_COMMON_WITH_INTERGATION, resetInitCommonWithIntergation)]; +var _default = exports.default = managerSagas; \ No newline at end of file diff --git a/dist/sagas/saga_meta.js b/dist/sagas/saga_meta.js new file mode 100644 index 00000000..6b3be549 --- /dev/null +++ b/dist/sagas/saga_meta.js @@ -0,0 +1,44 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; +var _effects = require("redux-saga/effects"); +var _action_type = require("../constants/action_type"); +var _peakInterval = require("../third_party/peakInterval"); +function* updateMetaPeaks(action) { + const { + payload + } = action; + const { + intervalL, + intervalR + } = (0, _peakInterval.getPeakIntervals)(payload); + const { + observeFrequency, + data + } = payload.spectra[0]; + const deltaX = Math.abs(data[0].x[0] - data[0].x[1]); + yield (0, _effects.put)({ + type: _action_type.META.UPDATE_PEAKS_RDC, + payload: { + peaks: { + intervalL, + intervalR, + observeFrequency, + deltaX + } + } + }); +} +function* updateMetaData(action) { + yield (0, _effects.put)({ + type: _action_type.META.UPDATE_META_DATA_RDC, + payload: { + dscMetaData: action.payload + } + }); +} +const metaSagas = [(0, _effects.takeEvery)(_action_type.META.UPDATE_PEAKS, updateMetaPeaks), (0, _effects.takeEvery)(_action_type.META.UPDATE_META_DATA, updateMetaData)]; +var _default = exports.default = metaSagas; \ No newline at end of file diff --git a/dist/sagas/saga_multi_entities.js b/dist/sagas/saga_multi_entities.js new file mode 100644 index 00000000..b32e30a8 --- /dev/null +++ b/dist/sagas/saga_multi_entities.js @@ -0,0 +1,202 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; +var _effects = require("redux-saga/effects"); +var _action_type = require("../constants/action_type"); +var _list_layout = require("../constants/list_layout"); +var _format = _interopRequireDefault(require("../helpers/format")); +/* eslint-disable no-plusplus */ + +const getLayoutSt = state => state.layout; +const getCurveSt = state => state.curve; +const getIntegrationSt = state => state.integration.present; +const getMultiplicitySt = state => state.multiplicity.present; +function getMaxMinPeak(curve) { + return curve.maxminPeak; +} +function* setCyclicVoltametry(action) { + // eslint-disable-line + const curveSt = yield (0, _effects.select)(getCurveSt); + const { + listCurves + } = curveSt; + if (listCurves) { + yield (0, _effects.put)({ + type: _action_type.CYCLIC_VOLTA_METRY.RESETALL, + payload: null + }); + const numberOfCurves = listCurves.length; + if (numberOfCurves <= 0) { + return; + } + const firstCurve = listCurves[0]; + const { + layout + } = firstCurve; + if (layout !== _list_layout.LIST_LAYOUT.CYCLIC_VOLTAMMETRY) { + return; + } + for (let index = 0; index < listCurves.length; index++) { + const curve = listCurves[index]; + const maxminPeak = getMaxMinPeak(curve); + yield (0, _effects.put)({ + type: _action_type.CYCLIC_VOLTA_METRY.ADD_PAIR_PEAKS, + payload: index + }); + for (let pidx = 0; pidx < maxminPeak.max.length; pidx++) { + const maxPeak = maxminPeak.max[pidx]; + yield (0, _effects.put)({ + type: _action_type.CYCLIC_VOLTA_METRY.ADD_MAX_PEAK, + payload: { + peak: maxPeak, + index: pidx, + jcampIdx: index + } + }); + const minPeak = maxminPeak.min[pidx]; + yield (0, _effects.put)({ + type: _action_type.CYCLIC_VOLTA_METRY.ADD_MIN_PEAK, + payload: { + peak: minPeak, + index: pidx, + jcampIdx: index + } + }); + const pecker = maxminPeak.pecker[pidx]; + yield (0, _effects.put)({ + type: _action_type.CYCLIC_VOLTA_METRY.ADD_PECKER, + payload: { + peak: pecker, + index: pidx, + jcampIdx: index + } + }); + } + const { + refIndex + } = maxminPeak; + if (refIndex > -1) { + yield (0, _effects.put)({ + type: _action_type.CYCLIC_VOLTA_METRY.SELECT_REF_PEAK, + payload: { + index: refIndex, + jcampIdx: index, + checked: true + } + }); + } + } + } +} +function* setCyclicVoltametryRef(action) { + // eslint-disable-line + const layoutSt = yield (0, _effects.select)(getLayoutSt); + if (layoutSt !== _list_layout.LIST_LAYOUT.CYCLIC_VOLTAMMETRY) { + return; + } + const curveSt = yield (0, _effects.select)(getCurveSt); + const { + curveIdx + } = curveSt; + yield (0, _effects.put)({ + type: _action_type.CYCLIC_VOLTA_METRY.SET_REF, + payload: { + jcampIdx: curveIdx + } + }); +} +function* setInitIntegrations(action) { + // eslint-disable-line + const curveSt = yield (0, _effects.select)(getCurveSt); + const { + listCurves + } = curveSt; + if (listCurves) { + for (let index = 0; index < listCurves.length; index++) { + const integationSt = yield (0, _effects.select)(getIntegrationSt); + const multiplicitySt = yield (0, _effects.select)(getMultiplicitySt); + const curve = listCurves[index]; + const { + integration, + multiplicity, + simulation + } = curve; + if (integration) { + const { + integrations + } = integationSt; + const newArrIntegration = [...integrations]; + if (index < newArrIntegration.length) { + newArrIntegration[index] = integration; + } else { + newArrIntegration.push(integration); + } + const payload = Object.assign({}, integationSt, { + integrations: newArrIntegration, + selectedIdx: index + }); // eslint-disable-line + yield (0, _effects.put)({ + type: _action_type.INTEGRATION.RESET_ALL_RDC, + payload + }); + } + if (multiplicity) { + const { + multiplicities + } = multiplicitySt; + const newArrMultiplicities = [...multiplicities]; + if (index < newArrMultiplicities.length) { + newArrMultiplicities[index] = multiplicity; + } else { + newArrMultiplicities.push(multiplicity); + } + const payload = Object.assign({}, multiplicitySt, { + multiplicities: newArrMultiplicities, + selectedIdx: index + }); // eslint-disable-line + yield (0, _effects.put)({ + type: _action_type.MULTIPLICITY.RESET_ALL_RDC, + payload + }); + } + if (simulation) { + yield (0, _effects.put)({ + type: _action_type.SIMULATION.RESET_ALL_RDC, + payload: simulation + }); + } + } + } +} +function* setSimulationForCurve(action) { + // eslint-disable-line + const layoutSt = yield (0, _effects.select)(getLayoutSt); + if (!_format.default.isNmrLayout(layoutSt)) return; + const curveSt = yield (0, _effects.select)(getCurveSt); + const { + listCurves, + curveIdx + } = curveSt; + if (!Array.isArray(listCurves) || listCurves.length === 0) return; + const targetIdx = Number.isInteger(action.payload) ? action.payload : curveIdx; + const targetCurve = listCurves[targetIdx]; + if (!targetCurve || !targetCurve.simulation) { + yield (0, _effects.put)({ + type: _action_type.SIMULATION.RESET_ALL_RDC, + payload: { + nmrSimPeaks: [] + } + }); + return; + } + yield (0, _effects.put)({ + type: _action_type.SIMULATION.RESET_ALL_RDC, + payload: targetCurve.simulation + }); +} +const multiEntitiesSagas = [(0, _effects.takeEvery)(_action_type.CURVE.SET_ALL_CURVES, setCyclicVoltametry), (0, _effects.takeEvery)(_action_type.CURVE.SET_ALL_CURVES, setInitIntegrations), (0, _effects.takeEvery)(_action_type.CURVE.SELECT_WORKING_CURVE, setSimulationForCurve), (0, _effects.takeEvery)(_action_type.CYCLIC_VOLTA_METRY.SET_FACTOR, setCyclicVoltametryRef)]; +var _default = exports.default = multiEntitiesSagas; \ No newline at end of file diff --git a/dist/sagas/saga_multiplicity.js b/dist/sagas/saga_multiplicity.js new file mode 100644 index 00000000..7529be27 --- /dev/null +++ b/dist/sagas/saga_multiplicity.js @@ -0,0 +1,379 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; +var _effects = require("redux-saga/effects"); +var _action_type = require("../constants/action_type"); +var _multiplicity_calc = require("../helpers/multiplicity_calc"); +var _multiplicity_manual = require("../helpers/multiplicity_manual"); +const getMetaSt = state => state.meta; +const getCurveSt = state => state.curve; +const getMultiplicitySt = state => state.multiplicity.present; +function* selectMpy(action) { + const metaSt = yield (0, _effects.select)(getMetaSt); + const mpySt = yield (0, _effects.select)(getMultiplicitySt); + const { + newData, + curveIdx + } = action.payload; + const { + multiplicities + } = mpySt; + let selectedMulti = multiplicities[curveIdx]; + if (selectedMulti === false || selectedMulti === undefined) { + selectedMulti = { + stack: [], + shift: 0, + smExtext: false, + edited: false + }; + } + const { + xExtent, + yExtent, + dataPks + } = newData; + const { + shift, + stack + } = selectedMulti; + const { + xL, + xU + } = xExtent; + const { + yL, + yU + } = yExtent; + let peaks = dataPks.filter(p => xL <= p.x && p.x <= xU && yL <= p.y && p.y <= yU); + peaks = peaks.map(pk => ({ + x: pk.x + shift, + y: pk.y + })); + const newXExtemt = { + xL: xL + shift, + xU: xU + shift + }; + const coupling = (0, _multiplicity_calc.calcMpyCoup)(peaks, metaSt); + const m = { + peaks, + xExtent: newXExtemt, + yExtent, + mpyType: coupling.type, + js: coupling.js + }; + const newStack = [...stack, m]; + const newSelectedMulti = Object.assign( + // eslint-disable-line + {}, selectedMulti, { + stack: newStack, + smExtext: newXExtemt + }); + const newMultiplicities = [...multiplicities]; + newMultiplicities[curveIdx] = newSelectedMulti; + const payload = Object.assign( + // eslint-disable-line + {}, mpySt, { + multiplicities: newMultiplicities, + selectedIdx: curveIdx + }); + yield (0, _effects.put)({ + type: _action_type.UI.SWEEP.SELECT_MULTIPLICITY_RDC, + payload + }); +} +function* addUiPeakToStack(action) { + const metaSt = yield (0, _effects.select)(getMetaSt); + const mpySt = yield (0, _effects.select)(getMultiplicitySt); + const curveSt = yield (0, _effects.select)(getCurveSt); + const { + curveIdx + } = curveSt; + const { + multiplicities + } = mpySt; + const selectedMulti = multiplicities[curveIdx]; + const { + shift, + stack, + smExtext + } = selectedMulti; + let { + x, + y + } = action.payload; // eslint-disable-line + if (!x || !y) return; + x += shift; + const newPeak = { + x, + y + }; + const { + xL, + xU + } = smExtext; + if (x < xL || xU < x) return; + let isDuplicate = false; + const newStack = stack.map(k => { + if (k.xExtent.xL === xL && k.xExtent.xU === xU) { + const existXs = k.peaks.map(pk => pk.x); + if (existXs.indexOf(newPeak.x) >= 0) { + isDuplicate = true; + return k; + } + const newPks = [...k.peaks, newPeak]; + const coupling = (0, _multiplicity_calc.calcMpyCoup)(newPks, metaSt); + return Object.assign( + // eslint-disable-line + {}, k, { + peaks: newPks, + mpyType: coupling.type, + js: coupling.js + }); + } + return k; + }); + if (isDuplicate) return; + const newSelectedMulti = Object.assign({}, selectedMulti, { + stack: newStack + }); // eslint-disable-line + const newMultiplicities = [...multiplicities]; + newMultiplicities[curveIdx] = newSelectedMulti; + const payload = Object.assign({}, mpySt, { + multiplicities: newMultiplicities + }); // eslint-disable-line + + yield (0, _effects.put)({ + type: _action_type.MULTIPLICITY.PEAK_ADD_BY_UI_RDC, + payload + }); +} +const rmPeakFromStack = function rmPeakFromStack(action, metaSt, mpySt) { + let curveIdx = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 0; + const { + peak, + xExtent + } = action.payload; + const { + multiplicities + } = mpySt; + const selectedMulti = multiplicities[curveIdx]; + const { + stack + } = selectedMulti; + let newStack = stack.map(k => { + if (k.xExtent.xL === xExtent.xL && k.xExtent.xU === xExtent.xU) { + const newPks = k.peaks.filter(pk => pk.x !== peak.x); + const coupling = (0, _multiplicity_calc.calcMpyCoup)(newPks, metaSt); + return Object.assign( + // eslint-disable-line + {}, k, { + peaks: newPks, + mpyType: coupling.type, + js: coupling.js + }); + } + return k; + }); + newStack = newStack.filter(k => k.peaks.length !== 0); + if (newStack.length === 0) { + const newSelectedMulti = Object.assign({}, selectedMulti, { + stack: newStack, + smExtext: false + }); // eslint-disable-line + multiplicities[curveIdx] = newSelectedMulti; + return Object.assign({}, mpySt, { + multiplicities + }); // eslint-disable-line + } + const noSmExtext = newStack.map(k => k.xExtent.xL === xExtent.xL && k.xExtent.xU === xExtent.xU ? 1 : 0).reduce((a, s) => a + s) === 0; + const newSmExtext = noSmExtext ? newStack[0].xExtent : xExtent; + const newSelectedMulti = Object.assign({}, selectedMulti, { + stack: newStack, + smExtext: newSmExtext + }); // eslint-disable-line + const newMultiplicities = [...multiplicities]; + newMultiplicities[curveIdx] = newSelectedMulti; + return Object.assign({}, mpySt, { + multiplicities: newMultiplicities + }); // eslint-disable-line +}; +function* rmPanelPeakFromStack(action) { + const metaSt = yield (0, _effects.select)(getMetaSt); + const mpySt = yield (0, _effects.select)(getMultiplicitySt); + const curveSt = yield (0, _effects.select)(getCurveSt); + const { + curveIdx + } = curveSt; + const payload = rmPeakFromStack(action, metaSt, mpySt, curveIdx); + yield (0, _effects.put)({ + type: _action_type.MULTIPLICITY.PEAK_RM_BY_PANEL_RDC, + payload + }); +} +function* rmUiPeakFromStack(action) { + const metaSt = yield (0, _effects.select)(getMetaSt); + const mpySt = yield (0, _effects.select)(getMultiplicitySt); + const curveSt = yield (0, _effects.select)(getCurveSt); + const { + curveIdx + } = curveSt; + const { + multiplicities + } = mpySt; + const selectedMulti = multiplicities[curveIdx]; + const peak = action.payload; + const xExtent = selectedMulti.smExtext; + const newAction = Object.assign({}, action, { + payload: { + peak, + xExtent + } + }); // eslint-disable-line + + const payload = rmPeakFromStack(newAction, metaSt, mpySt, curveIdx); + yield (0, _effects.put)({ + type: _action_type.MULTIPLICITY.PEAK_RM_BY_UI_RDC, + payload + }); +} +function* resetInitNmr(action) { + const { + multiplicity + } = action.payload; + const curveSt = yield (0, _effects.select)(getCurveSt); + const mpySt = yield (0, _effects.select)(getMultiplicitySt); + const { + curveIdx + } = curveSt; + const { + multiplicities + } = mpySt; + const newMultiplicities = [...multiplicities]; + newMultiplicities[curveIdx] = multiplicity; + const payload = Object.assign({}, mpySt, { + multiplicities: newMultiplicities, + selectedIdx: curveIdx + }); // eslint-disable-line + + if (multiplicity) { + yield (0, _effects.put)({ + type: _action_type.MULTIPLICITY.RESET_ALL_RDC, + payload + }); + } + // const metaSt = yield select(getMetaSt); + // const mpySt = yield select(getMultiplicitySt); + + // if (!multiplicity) { + // yield put({ + // type: MULTIPLICITY.RESET_ALL_RDC, + // payload: mpySt, + // }); + // } + + // const { stack } = multiplicity; + // const newStack = stack.map((k) => { + // const { peaks } = k; + // const coupling = calcMpyCoup(peaks, metaSt); + // return Object.assign( + // {}, + // k, + // { + // peaks, + // mpyType: coupling.type, + // js: coupling.js, + // }, + // ); + // }); + // const payload = Object.assign({}, mpySt, { stack: newStack }); + // yield put({ + // type: MULTIPLICITY.RESET_ALL_RDC, + // payload, + // }); +} +function* resetOne(action) { + const xExtent = action.payload; + const metaSt = yield (0, _effects.select)(getMetaSt); + const mpySt = yield (0, _effects.select)(getMultiplicitySt); + const curveSt = yield (0, _effects.select)(getCurveSt); + const { + curveIdx + } = curveSt; + const { + multiplicities + } = mpySt; + const selectedMulti = multiplicities[curveIdx]; + const { + stack + } = selectedMulti; + const newStack = stack.map(k => { + if (k.xExtent.xL === xExtent.xL && k.xExtent.xU === xExtent.xU) { + const { + peaks + } = k; + const coupling = (0, _multiplicity_calc.calcMpyCoup)(peaks, metaSt); + return Object.assign( + // eslint-disable-line + {}, k, { + peaks, + mpyType: coupling.type, + js: coupling.js + }); + } + return k; + }); + const newSelectedMulti = Object.assign({}, selectedMulti, { + stack: newStack + }); // eslint-disable-line + const newMultiplicities = [...multiplicities]; + newMultiplicities[curveIdx] = newSelectedMulti; + const payload = Object.assign({}, mpySt, { + multiplicities: newMultiplicities + }); // eslint-disable-line + yield (0, _effects.put)({ + type: _action_type.MULTIPLICITY.RESET_ONE_RDC, + payload + }); +} +function* selectMpyType(action) { + const mpySt = yield (0, _effects.select)(getMultiplicitySt); + const metaSt = yield (0, _effects.select)(getMetaSt); + const curveSt = yield (0, _effects.select)(getCurveSt); + const { + curveIdx + } = curveSt; + const { + multiplicities + } = mpySt; + const selectedMulti = multiplicities[curveIdx]; + const { + mpyType, + xExtent + } = action.payload; + const { + stack + } = selectedMulti; + const newStack = stack.map(k => { + const isTargetStack = k.xExtent.xL === xExtent.xL && k.xExtent.xU === xExtent.xU; + if (isTargetStack) return (0, _multiplicity_manual.calcMpyManual)(k, mpyType, metaSt); + return k; + }); + const newSelectedMulti = Object.assign({}, selectedMulti, { + stack: newStack + }); // eslint-disable-line + const newMultiplicities = [...multiplicities]; + newMultiplicities[curveIdx] = newSelectedMulti; + const payload = Object.assign({}, mpySt, { + multiplicities: newMultiplicities + }); // eslint-disable-line + + yield (0, _effects.put)({ + type: _action_type.MULTIPLICITY.TYPE_SELECT_RDC, + payload + }); +} +const multiplicitySagas = [(0, _effects.takeEvery)(_action_type.UI.SWEEP.SELECT_MULTIPLICITY, selectMpy), (0, _effects.takeEvery)(_action_type.MULTIPLICITY.PEAK_ADD_BY_UI_SAG, addUiPeakToStack), (0, _effects.takeEvery)(_action_type.MULTIPLICITY.PEAK_RM_BY_PANEL, rmPanelPeakFromStack), (0, _effects.takeEvery)(_action_type.MULTIPLICITY.PEAK_RM_BY_UI, rmUiPeakFromStack), (0, _effects.takeEvery)(_action_type.MULTIPLICITY.TYPE_SELECT, selectMpyType), (0, _effects.takeEvery)(_action_type.MULTIPLICITY.RESET_ONE, resetOne), (0, _effects.takeEvery)(_action_type.MANAGER.RESET_INIT_NMR, resetInitNmr)]; +var _default = exports.default = multiplicitySagas; \ No newline at end of file diff --git a/dist/sagas/saga_ui.js b/dist/sagas/saga_ui.js new file mode 100644 index 00000000..adf16e94 --- /dev/null +++ b/dist/sagas/saga_ui.js @@ -0,0 +1,321 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; +var _effects = require("redux-saga/effects"); +var _action_type = require("../constants/action_type"); +var _list_ui = require("../constants/list_ui"); +var _list_layout = require("../constants/list_layout"); +const getUiSt = state => state.ui; +const getCurveSt = state => state.curve; +const calcPeaks = payload => { + const { + xExtent, + yExtent, + dataPks + } = payload; + if (!dataPks) return []; + const { + xL, + xU + } = xExtent; + const { + yL, + yU + } = yExtent; + const peaks = dataPks.filter(p => xL <= p.x && p.x <= xU && yL <= p.y && p.y <= yU); + return peaks; +}; +function* selectUiSweep(action) { + const uiSt = yield (0, _effects.select)(getUiSt); + const { + payload + } = action; + const curveSt = yield (0, _effects.select)(getCurveSt); + const { + curveIdx + } = curveSt; + switch (uiSt.sweepType) { + case _list_ui.LIST_UI_SWEEP_TYPE.ZOOMIN: + yield (0, _effects.put)({ + type: _action_type.UI.SWEEP.SELECT_ZOOMIN, + payload + }); + break; + case _list_ui.LIST_UI_SWEEP_TYPE.ZOOMRESET: + yield (0, _effects.put)({ + type: _action_type.UI.SWEEP.SELECT_ZOOMRESET, + payload + }); + break; + case _list_ui.LIST_UI_SWEEP_TYPE.INTEGRATION_ADD: + yield (0, _effects.put)({ + type: _action_type.UI.SWEEP.SELECT_INTEGRATION, + payload: { + newData: payload, + curveIdx + } + }); + break; + case _list_ui.LIST_UI_SWEEP_TYPE.MULTIPLICITY_SWEEP_ADD: + const peaks = calcPeaks(payload); // eslint-disable-line + if (peaks.length === 0) { + break; + } + const newPayload = Object.assign({}, payload, { + peaks + }); // eslint-disable-line + + yield (0, _effects.put)({ + type: _action_type.UI.SWEEP.SELECT_INTEGRATION, + payload: { + newData: newPayload, + curveIdx + } + }); + yield (0, _effects.put)({ + type: _action_type.UI.SWEEP.SELECT_MULTIPLICITY, + payload: { + newData: newPayload, + curveIdx + } + }); + break; + default: + break; + } + return null; +} +const getLayoutSt = state => state.layout; +function* scrollUiWheel(action) { + const layoutSt = yield (0, _effects.select)(getLayoutSt); + const { + payload + } = action; + const { + xExtent, + yExtent, + direction + } = payload; + const { + yL, + yU + } = yExtent; + const [yeL, yeU] = [yL + (yU - yL) * 0.1, yU - (yU - yL) * 0.1]; + const scale = direction ? 0.8 : 1.25; + let nextExtent = { + xExtent: false, + yExtent: false + }; + let [nyeL, nyeU, h, nytL, nytU] = [0, 1, 1, 0, 1]; + switch (layoutSt) { + case _list_layout.LIST_LAYOUT.IR: + case _list_layout.LIST_LAYOUT.RAMAN: + [nyeL, nyeU] = [yeL + (yeU - yeL) * (1 - scale), yeU]; + h = nyeU - nyeL; + [nytL, nytU] = [nyeL - 0.125 * h, nyeU + 0.125 * h]; + nextExtent = { + xExtent, + yExtent: { + yL: nytL, + yU: nytU + } + }; + break; + case _list_layout.LIST_LAYOUT.MS: + [nyeL, nyeU] = [0, yeL + (yeU - yeL) * scale]; + h = nyeU - nyeL; + [nytL, nytU] = [nyeL - 0.125 * h, nyeU + 0.125 * h]; + nextExtent = { + xExtent, + yExtent: { + yL: nytL, + yU: nytU + } + }; + break; + case _list_layout.LIST_LAYOUT.UVVIS: + case _list_layout.LIST_LAYOUT.HPLC_UVVIS: + case _list_layout.LIST_LAYOUT.TGA: + case _list_layout.LIST_LAYOUT.DSC: + case _list_layout.LIST_LAYOUT.XRD: + default: + [nyeL, nyeU] = [yeL, yeL + (yeU - yeL) * scale]; + h = nyeU - nyeL; + [nytL, nytU] = [nyeL - 0.125 * h, nyeU + 0.125 * h]; + nextExtent = { + xExtent, + yExtent: { + yL: nytL, + yU: nytU + } + }; + break; + } + yield (0, _effects.put)({ + type: _action_type.UI.SWEEP.SELECT_ZOOMIN, + payload: nextExtent + }); +} +const getUiSweepType = state => state.ui.sweepType; +function* clickUiTarget(action) { + const { + payload, + onPeak, + voltammetryPeakIdx, + onPecker + } = action; + const uiSweepType = yield (0, _effects.select)(getUiSweepType); + const curveSt = yield (0, _effects.select)(getCurveSt); + const { + curveIdx + } = curveSt; + if (uiSweepType === _list_ui.LIST_UI_SWEEP_TYPE.PEAK_ADD && !onPeak) { + yield (0, _effects.put)({ + type: _action_type.EDITPEAK.ADD_POSITIVE, + payload: { + dataToAdd: payload, + curveIdx + } + }); + } else if (uiSweepType === _list_ui.LIST_UI_SWEEP_TYPE.PEAK_DELETE && onPeak) { + yield (0, _effects.put)({ + type: _action_type.EDITPEAK.ADD_NEGATIVE, + payload: { + dataToAdd: payload, + curveIdx + } + }); + } else if (uiSweepType === _list_ui.LIST_UI_SWEEP_TYPE.ANCHOR_SHIFT && onPeak) { + yield (0, _effects.put)({ + type: _action_type.SHIFT.SET_PEAK, + payload: { + dataToSet: payload, + curveIdx + } + }); + } else if (uiSweepType === _list_ui.LIST_UI_SWEEP_TYPE.INTEGRATION_RM && onPeak) { + yield (0, _effects.put)({ + type: _action_type.INTEGRATION.RM_ONE, + payload: { + dataToRemove: payload, + curveIdx + } + }); + } else if (uiSweepType === _list_ui.LIST_UI_SWEEP_TYPE.MULTIPLICITY_ONE_RM && onPeak) { + yield (0, _effects.put)({ + type: _action_type.INTEGRATION.RM_ONE, + payload: { + dataToRemove: payload, + curveIdx + } + }); + } else if (uiSweepType === _list_ui.LIST_UI_SWEEP_TYPE.INTEGRATION_SET_REF && onPeak) { + yield (0, _effects.put)({ + type: _action_type.INTEGRATION.SET_REF, + payload: { + refData: payload, + curveIdx + } + }); + } else if (uiSweepType === _list_ui.LIST_UI_SWEEP_TYPE.MULTIPLICITY_ONE_CLICK && onPeak) { + const { + xExtent, + xL, + xU + } = payload; + if (xExtent) { + yield (0, _effects.put)({ + type: _action_type.MULTIPLICITY.ONE_CLICK_BY_UI, + payload: { + payloadData: xExtent, + curveIdx + } + }); + } else if (xL && xU) { + yield (0, _effects.put)({ + type: _action_type.MULTIPLICITY.ONE_CLICK_BY_UI, + payload: { + payloadData: { + xL, + xU + }, + curveIdx + } + }); + } + } else if (uiSweepType === _list_ui.LIST_UI_SWEEP_TYPE.MULTIPLICITY_PEAK_ADD) { + yield (0, _effects.put)({ + type: _action_type.MULTIPLICITY.PEAK_ADD_BY_UI_SAG, + payload + }); + } else if (uiSweepType === _list_ui.LIST_UI_SWEEP_TYPE.MULTIPLICITY_PEAK_RM && onPeak) { + yield (0, _effects.put)({ + type: _action_type.MULTIPLICITY.PEAK_RM_BY_UI, + payload + }); + } else if (uiSweepType === _list_ui.LIST_UI_SWEEP_TYPE.CYCLIC_VOLTA_ADD_MAX_PEAK && !onPeak) { + yield (0, _effects.put)({ + type: _action_type.CYCLIC_VOLTA_METRY.ADD_MAX_PEAK, + payload: { + peak: payload, + index: voltammetryPeakIdx, + jcampIdx: curveIdx + } + }); + } else if (uiSweepType === _list_ui.LIST_UI_SWEEP_TYPE.CYCLIC_VOLTA_RM_MAX_PEAK && onPeak) { + yield (0, _effects.put)({ + type: _action_type.CYCLIC_VOLTA_METRY.REMOVE_MAX_PEAK, + payload: { + index: voltammetryPeakIdx, + jcampIdx: curveIdx + } + }); + } else if (uiSweepType === _list_ui.LIST_UI_SWEEP_TYPE.CYCLIC_VOLTA_ADD_MIN_PEAK && !onPeak) { + yield (0, _effects.put)({ + type: _action_type.CYCLIC_VOLTA_METRY.ADD_MIN_PEAK, + payload: { + peak: payload, + index: voltammetryPeakIdx, + jcampIdx: curveIdx + } + }); + } else if (uiSweepType === _list_ui.LIST_UI_SWEEP_TYPE.CYCLIC_VOLTA_RM_MIN_PEAK && onPeak) { + yield (0, _effects.put)({ + type: _action_type.CYCLIC_VOLTA_METRY.REMOVE_MIN_PEAK, + payload: { + index: voltammetryPeakIdx, + jcampIdx: curveIdx + } + }); + } else if (uiSweepType === _list_ui.LIST_UI_SWEEP_TYPE.CYCLIC_VOLTA_ADD_PECKER && !onPecker) { + yield (0, _effects.put)({ + type: _action_type.CYCLIC_VOLTA_METRY.ADD_PECKER, + payload: { + peak: payload, + index: voltammetryPeakIdx, + jcampIdx: curveIdx + } + }); + } else if (uiSweepType === _list_ui.LIST_UI_SWEEP_TYPE.CYCLIC_VOLTA_RM_PECKER && onPecker) { + yield (0, _effects.put)({ + type: _action_type.CYCLIC_VOLTA_METRY.REMOVE_PECKER, + payload: { + index: voltammetryPeakIdx, + jcampIdx: curveIdx + } + }); + } else if (uiSweepType === _list_ui.LIST_UI_SWEEP_TYPE.CYCLIC_VOLTA_SET_REF && onPeak) { + yield (0, _effects.put)({ + type: _action_type.CYCLIC_VOLTA_METRY.SET_REF, + payload: { + index: voltammetryPeakIdx, + jcampIdx: curveIdx + } + }); + } +} +const managerSagas = [(0, _effects.takeEvery)(_action_type.UI.CLICK_TARGET, clickUiTarget), (0, _effects.takeEvery)(_action_type.UI.SWEEP.SELECT, selectUiSweep), (0, _effects.takeEvery)(_action_type.UI.WHEEL.SCROLL, scrollUiWheel)]; +var _default = exports.default = managerSagas; \ No newline at end of file diff --git a/dist/setupTests.js b/dist/setupTests.js new file mode 100644 index 00000000..fc453d7d --- /dev/null +++ b/dist/setupTests.js @@ -0,0 +1,8 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); +var _enzyme = _interopRequireDefault(require("enzyme")); +var _enzymeAdapterReact = _interopRequireDefault(require("@wojtekmaj/enzyme-adapter-react-17")); +_enzyme.default.configure({ + adapter: new _enzymeAdapterReact.default() +}); \ No newline at end of file diff --git a/dist/third_party/jAnalyzer.js b/dist/third_party/jAnalyzer.js new file mode 100644 index 00000000..7d25625b --- /dev/null +++ b/dist/third_party/jAnalyzer.js @@ -0,0 +1,590 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; +/* eslint-disable */ +// https://github.com/cheminfo-js/spectra/blob/master/packages/spectra-data/src/peakPicking/jAnalyzer.js + +/* + * This library implements the J analyser described by Cobas et al in the paper: + * A two-stage approach to automatic determination of 1H NMR coupling constants + */ +const patterns = ['s', 'd', 't', 'q', 'quint', 'h', 'sept', 'o', 'n']; +let symRatio = 1.5; +let maxErrorIter1 = 2.5; // Hz +let maxErrorIter2 = 1; // Hz +var _default = exports.default = { + /** + * The compilation process implements at the first stage a normalization procedure described by Golotvin et al. + * embedding in peak-component-counting method described by Hoyes et al. + * @param {object} signal + * @private + */ + compilePattern: function compilePattern(signal) { + signal.multiplicity = 'm'; + // 1.1 symmetrize + // It will add a set of peaks(signal.peaksComp) to the signal that will be used during + // the compilation process. The unit of those peaks will be in Hz + signal.symRank = symmetrizeChoiseBest(signal, maxErrorIter1, 1); + signal.asymmetric = true; + // Is the signal symmetric? + if (signal.symRank >= 0.95 && signal.peaksComp.length < 32) { + signal.asymmetric = false; + var i, j, n, P1, n2, maxFlagged; + let k = 1; + let Jc = []; + + // Loop over the possible number of coupling contributing to the multiplet + for (n = 0; n < 9; n++) { + // 1.2 Normalize. It makes a deep copy of the peaks before to modify them. + let peaks = normalize(signal, n); + // signal.peaksCompX = peaks; + let validPattern = false; // It will change to true, when we find the good patter + // Lets check if the signal could be a singulet. + if (peaks.length === 1 && n === 0) { + validPattern = true; + } else { + if (peaks.length <= 1) { + continue; + } + } + // 1.3 Establish a range for the Heights Hi [peaks.intensity*0.85,peaks.intensity*1.15]; + let ranges = getRanges(peaks); + n2 = Math.pow(2, n); + + // 1.4 Find a combination of integer heights Hi, one from each Si, that sums to 2^n. + let heights = null; + let counter = 1; + while (!validPattern && (heights = getNextCombination(ranges, n2)) !== null && counter < 400) { + // 2.1 Number the components of the multiplet consecutively from 1 to 2n, + // starting at peak 1 + let numbering = new Array(heights.length); + k = 1; + for (i = 0; i < heights.length; i++) { + numbering[i] = new Array(heights[i]); + for (j = 0; j < heights[i]; j++) { + numbering[i][j] = k++; + } + } + Jc = []; // The array to store the detected j-coupling + // 2.2 Set j = 1; J1 = P2 - P1. Flag components 1 and 2 as accounted for. + j = 1; + Jc.push(peaks[1].x - peaks[0].x); + P1 = peaks[0].x; + numbering[0].splice(0, 1); // Flagged + numbering[1].splice(0, 1); // Flagged + k = 1; + let nFlagged = 2; + maxFlagged = Math.pow(2, n) - 1; + while (Jc.length < n && nFlagged < maxFlagged && k < peaks.length) { + counter += 1; + // 4.1. Increment j. Set k to the number of the first unflagged component. + j++; + while (k < peaks.length && numbering[k].length === 0) { + k++; + } + if (k < peaks.length) { + // 4.2 Jj = Pk - P1. + Jc.push(peaks[k].x - peaks[0].x); + // Flag component k and, for each sum of the... + numbering[k].splice(0, 1); // Flageed + nFlagged++; + // Flag the other components of the multiplet + for (let u = 2; u <= j; u++) { + // TODO improve those loops + let jSum = 0; + for (i = 0; i < u; i++) { + jSum += Jc[i]; + } + for (i = 1; i < numbering.length; i++) { + // Maybe 0.25 Hz is too much? + if (Math.abs(peaks[i].x - (P1 + jSum)) < 0.25) { + numbering[i].splice(0, 1); // Flageed + nFlagged++; + break; + } + } + } + } + } + // Calculate the ideal patter by using the extracted j-couplings + let pattern = idealPattern(Jc); + // Compare the ideal pattern with the proposed intensities. + // All the intensities have to match to accept the multiplet + validPattern = true; + for (i = 0; i < pattern.length; i++) { + if (pattern[i].intensity !== heights[i]) { + validPattern = false; + } + } + } + // If we found a valid pattern we should inform about the pattern. + if (validPattern) { + updateSignal(signal, Jc); + } + } + } + // Before to return, change the units of peaksComp from Hz to PPM again + for (i = 0; i < signal.peaksComp.length; i++) { + signal.peaksComp[i].x /= signal.observe; + } + } +}; +/** + * @private + * update the signal + * @param {*} signal + * @param {*} Jc + */ +function updateSignal(signal, Jc) { + // Update the limits of the signal + let peaks = signal.peaksComp; // Always in Hz + let nbPeaks = peaks.length; + signal.startX = peaks[0].x / signal.observe - peaks[0].width; + signal.stopX = peaks[nbPeaks - 1].x / signal.observe + peaks[nbPeaks - 1].width; + + // signal.integralData.from = peaks[0].x / signal.observe - peaks[0].width * 3; + // signal.integralData.to = + // peaks[nbPeaks - 1].x / signal.observe + peaks[nbPeaks - 1].width * 3; + + // Compile the pattern and format the constant couplings + signal.maskPattern = signal.mask2; + signal.multiplicity = abstractPattern(signal, Jc); + signal.pattern = signal.multiplicity; // Our library depends on this parameter, but it is old + // console.log(signal); + /* if (DEBUG) { + console.log('Final j-couplings: ' + JSON.stringify(Jc)); + }*/ +} + +/** + * Returns the multiplet in the compact format + * @param {object} signal + * @param {object} Jc + * @return {string} + * @private + */ +function abstractPattern(signal, Jc) { + let tol = 0.05; + let i; + let pattern = ''; + let cont = 1; + let newNmrJs = []; + if (Jc && Jc.length > 0) { + Jc.sort(function (a, b) { + return Math.abs(b) - Math.abs(a); + }); + for (i = 0; i < Jc.length - 1; i++) { + if (Math.abs(Jc[i] - Jc[i + 1]) < tol) { + cont++; + } else { + newNmrJs.push({ + coupling: Math.abs(Jc[i]), + multiplicity: patterns[cont] + }); + pattern += patterns[cont]; + cont = 1; + } + } + newNmrJs.push({ + coupling: Math.abs(Jc[i]), + multiplicity: patterns[cont] + }); + pattern += patterns[cont]; + signal.nmrJs = newNmrJs; + } else { + pattern = 's'; + // if (Math.abs(signal.startX - signal.stopX) * signal.observe > 16) { + // pattern = 'br s'; + // } + } + return pattern; +} + +/** + * This function creates an ideal pattern from the given J-couplings + * @private + * @param {Array} Jc + * @return {*[]} + * @private + */ +function idealPattern(Jc) { + let hsum = Math.pow(2, Jc.length); + let i, j; + let pattern = [{ + x: 0, + intensity: hsum + }]; + // To split the initial height + for (i = 0; i < Jc.length; i++) { + for (j = pattern.length - 1; j >= 0; j--) { + pattern.push({ + x: pattern[j].x + Jc[i] / 2, + intensity: pattern[j].intensity / 2 + }); + pattern[j].x = pattern[j].x - Jc[i] / 2; + pattern[j].intensity = pattern[j].intensity / 2; + } + } + // To sum the heights in the same positions + pattern.sort(function compare(a, b) { + return a.x - b.x; + }); + for (j = pattern.length - 2; j >= 0; j--) { + if (Math.abs(pattern[j].x - pattern[j + 1].x) < 0.1) { + pattern[j].intensity += pattern[j + 1].intensity; + pattern.splice(j + 1, 1); + } + } + return pattern; +} + +/** + * Find a combination of integer heights Hi, one from each Si, that sums to 2n. + * @param {object} ranges + * @param {number} value + * @return {*} + * @private + */ +function getNextCombination(ranges, value) { + let half = Math.ceil(ranges.values.length * 0.5); + let lng = ranges.values.length; + let sum = 0; + let i, ok; + while (sum !== value) { + // Update the indexes to point at the next possible combination + ok = false; + while (!ok) { + ok = true; + ranges.currentIndex[ranges.active]++; + if (ranges.currentIndex[ranges.active] >= ranges.values[ranges.active].length) { + // In this case, there is no more possible combinations + if (ranges.active + 1 === half) { + return null; + } else { + // If this happens we need to try the next active peak + ranges.currentIndex[ranges.active] = 0; + ok = false; + ranges.active++; + } + } else { + ranges.active = 0; + } + } + // Sum the heights for this combination + sum = 0; + for (i = 0; i < half; i++) { + sum += ranges.values[i][ranges.currentIndex[i]] * 2; + } + if (ranges.values.length % 2 !== 0) { + sum -= ranges.values[half - 1][ranges.currentIndex[half - 1]]; + } + } + // If the sum is equal to the expected value, fill the array to return + if (sum === value) { + let heights = new Array(lng); + for (i = 0; i < half; i++) { + heights[i] = ranges.values[i][ranges.currentIndex[i]]; + heights[lng - i - 1] = ranges.values[i][ranges.currentIndex[i]]; + } + return heights; + } + return null; +} + +/** + * This function generates the possible values that each peak can contribute + * to the multiplet. + * @param {Array} peaks Array of objects with peaks information {intensity} + * @return {{values: Array, currentIndex: Array, active: number}} + * @private + */ +function getRanges(peaks) { + let ranges = new Array(peaks.length); + let currentIndex = new Array(peaks.length); + let min, max; + ranges[0] = [1]; + ranges[peaks.length - 1] = [1]; + currentIndex[0] = -1; + currentIndex[peaks.length - 1] = 0; + for (let i = 1; i < peaks.length - 1; i++) { + min = Math.round(peaks[i].intensity * 0.85); + max = Math.round(peaks[i].intensity * 1.15); + ranges[i] = []; + for (let j = min; j <= max; j++) { + ranges[i].push(j); + } + currentIndex[i] = 0; + } + return { + values: ranges, + currentIndex: currentIndex, + active: 0 + }; +} +/** + * Performs a symmetrization of the signal by using different aproximations to the center. + * It will return the result of the symmetrization that removes less peaks from the signal + * @param {object} signal + * @param {number} maxError + * @param {number} iteration + * @return {*} + * @private + */ +function symmetrizeChoiseBest(signal, maxError, iteration) { + let symRank1 = symmetrize(signal, maxError, iteration); + let tmpPeaks = signal.peaksComp; + let tmpMask = signal.mask; + let cs = signal.delta1; + signal.delta1 = (signal.peaks[0].x + signal.peaks[signal.peaks.length - 1].x) / 2; + let symRank2 = symmetrize(signal, maxError, iteration); + if (signal.peaksComp.length > tmpPeaks.length) { + return symRank2; + } else { + signal.delta1 = cs; + signal.peaksComp = tmpPeaks; + signal.mask = tmpMask; + return symRank1; + } +} + +/** + * This function will return a set of symmetric peaks that will + * be the enter point for the patter compilation process. + * @param {object} signal + * @param {number} maxError + * @param {number} iteration + * @return {number} + * @private + */ +function symmetrize(signal, maxError, iteration) { + // Before to symmetrize we need to keep only the peaks that possibly conforms the multiplete + let max, min, avg, ratio, avgWidth, i; + let peaks = new Array(signal.peaks.length); + // Make a deep copy of the peaks and convert PPM ot HZ + for (i = 0; i < peaks.length; i++) { + peaks[i] = { + x: signal.peaks[i].x * signal.observe, + intensity: signal.peaks[i].intensity, + width: signal.peaks[i].width + }; + } + // Join the peaks that are closer than 0.25 Hz + for (i = peaks.length - 2; i >= 0; i--) { + if (Math.abs(peaks[i].x - peaks[i + 1].x) < 0.25) { + peaks[i].x = peaks[i].x * peaks[i].intensity + peaks[i + 1].x * peaks[i + 1].intensity; + peaks[i].intensity = peaks[i].intensity + peaks[i + 1].intensity; + peaks[i].x /= peaks[i].intensity; + peaks[i].intensity /= 2; + peaks[i].width += peaks[i + 1].width; + peaks.splice(i + 1, 1); + } + } + signal.peaksComp = peaks; + let nbPeaks = peaks.length; + let mask = new Array(nbPeaks); + signal.mask = mask; + let left = 0; + let right = peaks.length - 1; + let cs = signal.delta1 * signal.observe; + let middle = [(peaks[0].x + peaks[nbPeaks - 1].x) / 2, 1]; + maxError = error(Math.abs(cs - middle[0])); + let heightSum = 0; + // We try to symmetrize the extreme peaks. We consider as candidates for symmetricing those which have + // ratio smaller than 3 + for (i = 0; i < nbPeaks; i++) { + mask[i] = true; + heightSum += signal.peaks[i].intensity; + } + while (left <= right) { + mask[left] = true; + mask[right] = true; + if (left === right) { + if (nbPeaks > 2 && Math.abs(peaks[left].x - cs) > maxError) { + mask[left] = false; + } + } else { + max = Math.max(peaks[left].intensity, peaks[right].intensity); + min = Math.min(peaks[left].intensity, peaks[right].intensity); + ratio = max / min; + if (ratio > symRatio) { + if (peaks[left].intensity === min) { + mask[left] = false; + right++; + } else { + mask[right] = false; + left--; + } + } else { + let diffL = Math.abs(peaks[left].x - cs); + let diffR = Math.abs(peaks[right].x - cs); + if (Math.abs(diffL - diffR) < maxError) { + avg = Math.min(peaks[left].intensity, peaks[right].intensity); + avgWidth = Math.min(peaks[left].width, peaks[right].width); + peaks[left].intensity = peaks[right].intensity = avg; + peaks[left].width = peaks[right].width = avgWidth; + middle = [middle[0] + (peaks[right].x + peaks[left].x) / 2, middle[1] + 1]; + } else { + if (Math.max(diffL, diffR) === diffR) { + mask[right] = false; + left--; + } else { + mask[left] = false; + right++; + } + } + } + } + left++; + right--; + // Only alter cs if it is the first iteration of the sym process. + if (iteration === 1) { + cs = chemicalShift(peaks, mask); + // There is not more available peaks + if (isNaN(cs)) { + return 0; + } + } + maxError = error(Math.abs(cs - middle[0] / middle[1])); + } + // To remove the weak peaks and recalculate the cs + for (i = nbPeaks - 1; i >= 0; i--) { + if (mask[i] === false) { + peaks.splice(i, 1); + } + } + cs = chemicalShift(peaks); + if (isNaN(cs)) { + return 0; + } + signal.delta1 = cs / signal.observe; + // Now, the peak should be symmetric in heights, but we need to know if it is symmetric in x + let symFactor = 0; + let weight = 0; + if (peaks.length > 1) { + for (i = Math.ceil(peaks.length / 2) - 1; i >= 0; i--) { + symFactor += (3 + Math.min(Math.abs(peaks[i].x - cs), Math.abs(peaks[peaks.length - 1 - i].x - cs))) / (3 + Math.max(Math.abs(peaks[i].x - cs), Math.abs(peaks[peaks.length - 1 - i].x - cs))) * peaks[i].intensity; + weight += peaks[i].intensity; + } + symFactor /= weight; + } else { + if (peaks.length === 1) { + symFactor = 1; + } + } + let newSumHeights = 0; + for (i = 0; i < peaks.length; i++) { + newSumHeights += peaks[i].intensity; + } + symFactor -= (heightSum - newSumHeights) / heightSum * 0.12; // Removed peaks penalty + // Sometimes we need a second opinion after the first symmetrization. + if (symFactor > 0.8 && symFactor < 0.97 && iteration < 2) { + return symmetrize(signal, maxErrorIter2, 2); + } else { + // Center the given pattern at cs and symmetrize x + if (peaks.length > 1) { + let dxi; + for (i = Math.ceil(peaks.length / 2) - 1; i >= 0; i--) { + dxi = (peaks[i].x - peaks[peaks.length - 1 - i].x) / 2.0; + peaks[i].x = cs + dxi; + peaks[peaks.length - 1 - i].x = cs - dxi; + } + } + } + return symFactor; +} +/** + * Error validator + * @param {number} value + * @return {number} + * @private + */ +function error(value) { + let maxError = value * 2.5; + if (maxError < 0.75) { + maxError = 0.75; + } + if (maxError > 3) { + maxError = 3; + } + return maxError; +} +/** + * @private + * 2 stages normalizarion of the peaks heights to Math.pow(2,n). + * Creates a new mask with the peaks that could contribute to the multiplete + * @param {object} signal + * @param {number} n + * @return {*} + */ +function normalize(signal, n) { + // Perhaps this is slow + let peaks = JSON.parse(JSON.stringify(signal.peaksComp)); + let norm = 0; + let norm2 = 0; + for (var i = 0; i < peaks.length; i++) { + norm += peaks[i].intensity; + } + norm = Math.pow(2, n) / norm; + signal.mask2 = JSON.parse(JSON.stringify(signal.mask)); + let index = signal.mask2.length - 1; + for (i = peaks.length - 1; i >= 0; i--) { + peaks[i].intensity *= norm; + while (index >= 0 && signal.mask2[index] === false) { + index--; + } + if (peaks[i].intensity < 0.75) { + peaks.splice(i, 1); + signal.mask2[index] = false; + } else { + norm2 += peaks[i].intensity; + } + index--; + } + norm2 = Math.pow(2, n) / norm2; + for (i = peaks.length - 1; i >= 0; i--) { + peaks[i].intensity *= norm2; + } + return peaks; +} + +/** + * @private + * Calculates the chemical shift as the weighted sum of the peaks + * @param {Array} peaks + * @param {Array} mask + * @return {number} + */ +function chemicalShift(peaks, mask) { + let sum = 0; + let cs = 0; + let i, area; + if (mask) { + for (i = 0; i < peaks.length; i++) { + if (mask[i] === true) { + area = getArea(peaks[i]); + sum += area; + cs += area * peaks[i].x; + } + } + } else { + for (i = 0; i < peaks.length; i++) { + area = getArea(peaks[i]); + sum += area; + cs += area * peaks[i].x; + } + } + return cs / sum; +} + +/** + * Return the area of a Lorentzian function + * @param {object} peak - object with peak information + * @return {number} + * @private + */ +function getArea(peak) { + return Math.abs(peak.intensity * peak.width * 1.57); // 1.772453851); +} \ No newline at end of file diff --git a/dist/third_party/peakInterval.js b/dist/third_party/peakInterval.js new file mode 100644 index 00000000..406996d0 --- /dev/null +++ b/dist/third_party/peakInterval.js @@ -0,0 +1,105 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.getPeakIntervals = void 0; +var _mlSavitzkyGolayGeneralized = _interopRequireDefault(require("ml-savitzky-golay-generalized")); +// https://github.com/mljs/global-spectral-deconvolution/blob/master/src/gsd.js + +/* eslint-disable no-plusplus, operator-linebreak */ + +const options = { + sgOptions: { + windowSize: 9, + polynomial: 3 + }, + minMaxRatio: 0.00025, + broadRatio: 0.0, + maxCriteria: true, + smoothY: true, + realTopDetection: false, + heightFactor: 0, + boundaries: false, + derivativeThreshold: -1 +}; +const getPeakIntervals = entity => { + const data = entity.spectra[0].data[0]; + const X = data.x; + const dX = X[1] - X[0]; + const Y = (0, _mlSavitzkyGolayGeneralized.default)(data.y, data.x, { + windowSize: options.sgOptions.windowSize, + polynomial: options.sgOptions.polynomial, + derivative: 0 + }); + const dY = (0, _mlSavitzkyGolayGeneralized.default)(data.y, data.x, { + windowSize: options.sgOptions.windowSize, + polynomial: options.sgOptions.polynomial, + derivative: 1 + }); + const ddY = (0, _mlSavitzkyGolayGeneralized.default)(data.y, data.x, { + windowSize: options.sgOptions.windowSize, + polynomial: options.sgOptions.polynomial, + derivative: 2 + }); + let maxDdy = 0; + let maxY = 0; + for (let i = 0; i < Y.length; i++) { + if (Math.abs(ddY[i]) > maxDdy) { + maxDdy = Math.abs(ddY[i]); + } + if (Math.abs(Y[i]) > maxY) { + maxY = Math.abs(Y[i]); + } + } + let lastMax = null; + let lastMin = null; + const minddY = new Array(Y.length - 2); + const intervalL = new Array(Y.length); + const intervalR = new Array(Y.length); + const broadMask = new Array(Y.length - 2); + let minddYLen = 0; + let intervalLLen = 0; + let intervalRLen = 0; + let broadMaskLen = 0; + for (let i = 1; i < Y.length - 1; ++i) { + // filter based on derivativeThreshold + if (Math.abs(dY[i]) > options.derivativeThreshold) { + // Minimum in first derivative + if (dY[i] < dY[i - 1] && dY[i] <= dY[i + 1] || dY[i] <= dY[i - 1] && dY[i] < dY[i + 1]) { + lastMin = { + x: X[i], + index: i + }; + if (dX > 0 && lastMax !== null) { + intervalL[intervalLLen++] = lastMax; + intervalR[intervalRLen++] = lastMin; + } + } + + // Maximum in first derivative + if (dY[i] >= dY[i - 1] && dY[i] > dY[i + 1] || dY[i] > dY[i - 1] && dY[i] >= dY[i + 1]) { + lastMax = { + x: X[i], + index: i + }; + if (dX < 0 && lastMin !== null) { + intervalL[intervalLLen++] = lastMax; + intervalR[intervalRLen++] = lastMin; + } + } + } + // Minimum in second derivative + if (ddY[i] < ddY[i - 1] && ddY[i] < ddY[i + 1]) { + // TODO should we change this to have 3 arrays ? Huge overhead creating arrays + minddY[minddYLen++] = i; // ( [X[i], Y[i], i] ); + broadMask[broadMaskLen++] = Math.abs(ddY[i]) <= options.broadRatio * maxDdy; + } + } + return { + intervalL, + intervalR + }; +}; +exports.getPeakIntervals = getPeakIntervals; \ No newline at end of file From a2f8e03f0b5ed393082f769f032cbed296d65b32 Mon Sep 17 00:00:00 2001 From: Nicolass67 Date: Mon, 2 Feb 2026 09:47:45 +0100 Subject: [PATCH 4/4] fix: enhance null checks and default predictions handling in forecast components --- src/components/forecast/comps.js | 5 +++-- src/components/forecast/ir_viewer.js | 4 ++-- src/components/forecast/nmr_viewer.js | 3 ++- src/reducers/reducer_forecast.js | 1 + 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/components/forecast/comps.js b/src/components/forecast/comps.js index 3107119a..ad784b90 100644 --- a/src/components/forecast/comps.js +++ b/src/components/forecast/comps.js @@ -180,6 +180,7 @@ const SectionUnknown = () => ( ); const notToRenderAnalysis = (pds) => { + if (!pds) return
; if (pds.running) return ; if (!pds.outline || !pds.outline.code) return
; @@ -193,8 +194,8 @@ const sectionSvg = (classes, predictions) => { const renderMsg = notToRenderAnalysis(predictions); if (renderMsg) return null; - if (!predictions.output) return null; - const targetSvg = predictions.output.result[0].svgs[0]; + if (!predictions || !predictions.output || !predictions.output.result || !predictions.output.result[0]) return null; + const targetSvg = predictions.output.result[0].svgs && predictions.output.result[0].svgs[0]; if (!targetSvg) return ; return ( { const renderMsg = notToRenderAnalysis(pds); if (renderMsg) return renderMsg; - if (!pds.output.result || !pds.output.result[0]) return null; + if (!pds || !pds.output || !pds.output.result || !pds.output.result[0]) return null; const { fgs } = pds.output.result[0]; if (!fgs) return null; @@ -88,7 +88,7 @@ const IrViewer = ({ // eslint-disable-line const hasCurvePredictions = Object.prototype.hasOwnProperty.call(predictionsByCurve, curveIdx); const hasAnyCurvePredictions = Object.keys(predictionsByCurve).length > 0; const emptyPredictions = { outline: {}, output: { result: [] } }; - let activePredictions = forecastSt.predictions; + let activePredictions = forecastSt.predictions || emptyPredictions; if (hasCurvePredictions) { activePredictions = predictionsByCurve[curveIdx]; } else if (hasAnyCurvePredictions) { diff --git a/src/components/forecast/nmr_viewer.js b/src/components/forecast/nmr_viewer.js index ba6f7366..aee23bba 100644 --- a/src/components/forecast/nmr_viewer.js +++ b/src/components/forecast/nmr_viewer.js @@ -62,6 +62,7 @@ const sectionTable = (classes, pds) => { const renderMsg = notToRenderAnalysis(pds); if (renderMsg) return renderMsg; + if (!pds || !pds.output || !pds.output.result || !pds.output.result[0]) return
; const dict = pds.output.result[0]; if (!dict) return
; return ( @@ -88,7 +89,7 @@ const NmrViewer = ({ // eslint-disable-line const hasCurvePredictions = Object.prototype.hasOwnProperty.call(predictionsByCurve, curveIdx); const hasAnyCurvePredictions = Object.keys(predictionsByCurve).length > 0; const emptyPredictions = { outline: {}, output: { result: [] } }; - let activePredictions = forecastSt.predictions; + let activePredictions = forecastSt.predictions || emptyPredictions; if (hasCurvePredictions) { activePredictions = predictionsByCurve[curveIdx]; } else if (hasAnyCurvePredictions) { diff --git a/src/reducers/reducer_forecast.js b/src/reducers/reducer_forecast.js index ecc749b2..397860a9 100644 --- a/src/reducers/reducer_forecast.js +++ b/src/reducers/reducer_forecast.js @@ -121,6 +121,7 @@ const forecastReducer = (state = initialState, action) => { {}, state, payloadRest, + { predictions: nextPredictions }, ); if (!Number.isInteger(curveIdx)) { return nextState;