---
# System prepended metadata

title: Refactor of the state

---

# 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
      }
    }
  }
}
```

  