# Refactor of the state ## Current state ### Global state (put here the name of the context) ### We have three contexts: 1. Global State [https://github.com/cheminfo/nmrium/blob/master/src/component/reducer/Reducer.ts#L59-L126](https://github.com/cheminfo/nmrium/blob/master/src/component/reducer/Reducer.ts#L59-L126) contain all the data. 2. Preferences State [https://github.com/cheminfo/nmrium/blob/master/src/component/reducer/preferencesReducer.ts#L31-L75](https://) contain the global preferences of NMRium and its panels 3. Scale state https://github.com/cheminfo/nmrium/blob/master/src/component/reducer/scaleReducer.ts#L19-L22 contain scale x and y functions and i use it for 1D only ## New state - PreferencesReducer: General preferences - DataReducer: contains the data that are saved in the JSON - DisplayReducer: contains everything related to what is displayed and the how it is displayed - DataProcessingReducer: contains data that are temporarely calculated ## PreferencesReducer ## DataReducer Should contain everything we save in the JSON By storing the data as an object we think that it will simplify the code ```json= { "spectra": { "1H": [ { "id": "", "display": { "name": "", "color": "", "isVisible": true, "isPeaksMarkersVisible": true, "isRealSpectrumVisible": true }, "source": { "jcampURL": "//", "file": { "binary": null, "name": "", "extension": "" } }, "meta": [ //this data completely come from converter package and we just display it and not use it in any operation ], "info": { "nucleus": "1H", // 1H, 13C, 19F, ... "isFid": false, "isFt": true, "isComplex": false, // if isComplex is true that mean it contains real/ imaginary x set, if not hid re/im button . "dimension": 1 //Most if these information come from the original files (jcamp,jeol, bruker ... etc) }, "originlInfo": { //similar to "info" object but the difference is when we apply the filter or enable/disable it we still need the info before any changes, with it's original form }, "data": { "x": [], "re": [], "im": [], }, "originalData": { //similar to "data" object and act as the same we did with info and originalInfo object }, "peaks": { "options": {}, "values": [ { "intensity": 1000, "width": 0, "originDelta": 5, // before shift,this store in json as "delta" "delta": 5 // (originDelta + accumative shift) include shift and we neglect it when export as json file } //.... etc ] }, "ranges": { "options": { "sum": 100, "isSumConstant": false }, "values": [ { "id": "", // unique Key "originFrom": 5, // before shift (shift value change base on the shift filter),this store in json as "from" "originTo": 6, // before shift,this store in json as "to" "from": 5, // (originFrom + accumative shift) include shift and we neglect it when export as json file "to": 6, // (originTo + accumative shift) include shift and we neglect it when export as json file "absolute": 10000, "integration": 100, "kind": "signal", "signals": [ {} ] } // ... etc ] }, "integrals": { "options": { "sum": 100, "isSumConstant": false }, "values": [ { "id": "", // unique Key "originFrom": 5, // before shift (shift value change base on the shift filter),this store in json as "from" "originTo": 6, // before shift,this store in json as "to" "from": 5, // (originFrom + accumative shift) include shift and we neglect it when export as json file "to": 6, // (originTo + accumative shift) include shift and we neglect it when export as json file "absolute": 10000, "integral": 100, "kind": "signal" } // ... etc ] }, "filters": [ { "id": "", // unique Key for each record "name": "shiftFilter", // unique identifier per filter "label": "Shift Filter", "isDeleteAllow": false, // whether can be deleted or not "flag": false, // enable/disble filter "value": {} // filter criteria, it can hold any data type ( object, number, or string) } // ... etc ] } ], "1H,1H": [ { "id": "", "display": { "name": "", "positiveColor": "red", "negativeColor": "blue", "isPositiveVisible": true, "isNegativeVisible": true, "isVisible": true, "contourOptions": { "positive": { "contourLevels": [ 0, 21 ], "numberOfLayers": 10 }, "negative": { "contourLevels": [ 0, 21 ], "numberOfLayers": 10 } }, "dimension": 2 }, "source": { "jcampURL": "//" }, "info": { "nucleus": [ "1H", "1H" ], "isFt": true, "isFid": false, "isComplex": false, // if isComplex is true that mean it contains real/ imaginary x set, if not hid re/im button . "dimension": 2 }, "originlInfo": { //similar to "info" object but the difference is when we apply the filter or enable/disable it we still need the info before any changes, with it's original form }, "data": { "z": [], "minX": 0, "minY": 0, "maxX": 0, "maxY": 0 }, "originalData": { //similar to "data" object and act as the same we did with info and originalInfo object }, "filters": [ { "id": "", // unique Key for each record "name": "xShiftFilter", // unique identifier per filter "label": "X Shift Filter", "isDeleteAllow": true, // whether can be deleted or not "flag": true, // enable/disble filter "value": {} // filter criteria, it can hold any data type ( object, number, or string) } // ... etc ], "zones": { "options": {}, "values": [ { "id": "", //unique key "x": { "from": 0, "to": 5 }, "y": { "from": 2, "to": 4 }, "signals": [ { "id": "", "peaks": [], "x": { "originDelta": 3, // before shift , this store in json as "delta" "delta": 3, // (originDelta + accumative shift) include shift and we neglect it when export as json file "diaIDs": [] }, "y": { "originDelta": 3, // before shift , this store in json as "delta" "delta": 3, // (originDelta + accumative shift) include shift and we neglect it when export as json file "diaIDs": [] }, "kind": "signal" } //... etc ], "kind": "signal" } //... etc ] }, "processingController": {} // Processing2D instance } ] }, "molecules": [ { "key": "", // unique identifier "molfile": "", "mf": "", // formula "em": 0, // Absolute Weight "mw": 0, // Relative Weight "svg": "", // an SVG string representing the structure in two dimensions "atoms": {} } // ... etc ], "correlations":{ // contain correlation object structure based on nmr-correlation library } } ``` ```json { spectra: { 'oneD': { '1H': [ { display: { color: }, data: { } } ], '13C': [], '19F': [], }, 'twoD': { '1H,1H': [], '1H,13C': [], } }, molecules: [] } ``` ## DisplayReducer ``` json= { /** * unique key identifier per Displayer instance */ "displayerKey": "", /** * boolean indicator to check if the mouse over the displayer or not * value change to true once the mouse come over the displayer and vice versa true once the mouse out of the displayer */ "overDisplayer": false, /** * X axis domain * value change when zooming in/out * Array<number> */ "xDomain": [], /** * Y axis domain * value change when vertical scale change for all spectra * Array<number> */ "yDomain": [], /** * Y axis domain per spectrum * value change when vertical scale change for the selected spectrum * Record<string, Array<number>> */ "yDomains": {}, /** * X axis domain per spectrum * value change when zooming in/out for the selected spectrum * Record<string, Array<number>> */ "xDomains": {}, /** * Domain for X and Y axis once it calculated and it change in one case when we load new spectra */ "originDomain": { "xDomain": [], "yDomain": [], "xDomains": {}, "yDomains": {}, "shareYDomain": true }, /** * current select tab (nucleus) */ "activeTab": null, /** * plot chart area width */ "width": 0, /** * plot chart area height */ "height": 0, /** * The margin Around the plot chart area */ "margin": { "top": 10, "right": 20, "bottom": 70, "left": 0 }, /** * current active spectrum * value can be null or object */ "activeSpectrum": { "id": "", "index": 0 }, /** * Scale direction * value can be 'RTL' | 'LTR' */ "mode": "RTL", /** * options to control spectra vertical alignment */ "verticalAlign": { "flag": true, // whether the spectrea are in the center or not "stacked": false, // whether the spectra are displayed as stack or not "value": 20, // shift value in px }, /** * hide/show main loading indicator */ "isLoading": false, /** * displayer mode '1D' or '2D' */ "displayerMode": "1D", /** * active spectrum per nucleus * default value {} */ "tabActiveSpectrum": { "1H": { "id": "", "index": 0 }, // ... etc }, /** * colors that used in 1d and 2d spectra */ "usedColors": { "1d": [], "2d": [] }, /** * Zoom Manager for vertical scale for spectra, integral, And undo zoom in per tab (nucleus) */ "zoom": { "history": { "1H": [ // store x and y domain in stack per nucleus { "xDomain": [ 1, 12 ], "yDomain": [ 1, 220 ] }, { "xDomain": [ 5, 10 ], "yDomain": [ 1, 220 ] } // ... etc ] }, "spectra": { "scales": { "spectra id": 1, //... etc }, "options": { "slowZoomStep": 1, "fastZoomStep": 20, "speedThreshold": 5 } }, "integral": { "scales": { "spectra id": 1, //... etc }, "options": { "slowZoomStep": 1, "fastZoomStep": 20, "speedThreshold": 5 } } } } }, /** * Basic options for the tools */ "toolOptions": { /** * The current selected tool */ "selectedTool": "zoom", /** * The current active options panel * Part of tools has an options panel for more control over the tool, once the user select the tool then the options panel will be shown in the header */ "selectedOptionPanel": null, /** * extra data for tools */ "data": { /** * list of zones for Baseline correction filter */ "baseLineZones": [ { "id": "", "from": 1, "to": 2 } // ...etc ], /** * list of exclusive zones per nucleus */ "exclusionZones": { "1H": [ { "id": "", "from": 1, "to": 2 } //... etc ] //... etc }, /** * pivot point for manual phase correction * @default {value:0,index:0} */ "pivot": { "value": 5, "index": 0 }, /** * Noise factor for auto zones detection */ "zonesNoiseFactor": 1, /** * The current active Filter */ "activeFilterID": null, /** * copy of the range that the user start editing for multiplicity tree live updating */ "tempRange": null, /** * boolean indicator to hide/show multiplicity tree */ "showMultiplicityTrees": false, /** * boolean indicator to hide/show integrals for the spectrum ranges * @default false */ "showRangesIntegrals": false } } } ``` ## DataProcessingReducer ``` json= { /** * snapshot of the spectra data once phase correction activated * */ "tempData": [ { /*spectrum data*/}, //... etc ], /** * calculated contours for 2d spectra */ "contours": { "<<spectrum Id>>": { "negative": [], "positive": [] } //... etc } /** * temporary snapshot of state once the user press on number from 1-9 */ "keysPreferences": { "<<number>>": { /*clone part of the state*/}, // ..etc }, "spectraAnalysis": { "1H": { "options": { "sum": 100, "code": "", "columns": [ { "type": "NORMAL", // NORMAL | FORMULA "valueKey": "relative", // relative | absolute | min | max "from": 2, "to": 4, "formula": "", // formular as string, for example (A+B) "index": 0 } // ... etc ], "columnIndex": 0 }, "values": { "column key": { "SID": "spectrum id", "colKey": "A", "value": 100 } //... etc } } } } ```