Skip to content
Snippets Groups Projects
points.js 3.43 KiB
Newer Older
  • Learn to ignore specific revisions
  • const { createSelector, defaultMemoize: memoize } = require('reselect');
    
    const { setEquality } = require('../../utils');
    
    const MASK_DESC = {
        ice: 'Ice',
        fld: 'Flood',
        bkw: 'Backwater',
        zfl: 'Zeroflow',
        dry: 'Dry',
        ssn: 'Seasonal',
        pr: 'Partial Record',
        rat: 'Rating Development',
        eqp: 'Equipment Malfunction',
        mnt: 'Maintenance',
        dis: 'Discontinued',
        tst: 'Test',
        pmp: 'Pump',
        '***': 'Unavailable'
    };
    
    /**
     * Returns the points for a given timeseries.
     * @param  {Object} state     Redux store
     * @param  {String} tsDataKey Timeseries key
     * @return {Array}            Array of points.
     */
    
    Yan, Andrew N.'s avatar
    Yan, Andrew N. committed
    const pointsSelector = memoize(tsDataKey => createSelector(
    
        state => state.tsData,
        tsData => tsData[tsDataKey]
    ));
    
     * Factory function creates a function that:
    
     * Returns the current show state of a timeseries.
     * @param  {Object}  state     Redux store
     * @param  {String}  tsDataKey Timeseries key
     * @return {Boolean}           Show state of the timeseries
     */
    
    const isVisibleSelector = memoize(tsDataKey => (state) => {
        return state.showSeries[tsDataKey];
    });
    
     * Factory function creates a function that:
    
     * Returns all points in a timeseries grouped into line segments.
    
     * @param  {Object} state     Redux store
     * @param  {String} tsDataKey Timeseries key
     * @return {Array}            Array of points.
     */
    
    const lineSegmentsSelector = memoize(tsDataKey => createSelector(
    
        (points) => {
            // Accumulate data into line groups, splitting on the estimated and
            // approval status.
            let lines = [];
    
    Yan, Andrew N.'s avatar
    Yan, Andrew N. committed
            let lastClasses = {};
    
            const masks = new Set(Object.keys(MASK_DESC));
    
                // Classes to put on the line with this point.
                let lineClasses = {
                    approved: pt.approved,
                    estimated: pt.estimated,
                    dataMask: null
                };
    
                    let qualifiers = new Set(pt.qualifiers.map(q => q.toLowerCase()));
    
    Yan, Andrew N.'s avatar
    Yan, Andrew N. committed
                    // current business rules specify that a particular data point
                    // will only have at most one masking qualifier
    
                    let maskIntersection = new Set([...masks].filter(x => qualifiers.has(x)));
    
                    lineClasses.dataMask = [...maskIntersection][0]
    
                else if (pt.value !== null) {
                    // Temporary check to help detect test sites.
                    if (pt.qualifiers.length > 1) {
                        /*eslint no-console: "allow"*/
                        console.error('Point has multiple qualifiers', pt.qualifiers);
                    }
    
                }
                // If this point doesn't have the same classes as the last point,
                // create a new line for it.
                if (lastClasses.approved !== lineClasses.approved ||
                        lastClasses.estimated !== lineClasses.estimated ||
                        lastClasses.dataMask !== lineClasses.dataMask) {
                    lines.push({
                        classes: lineClasses,
                        points: []
                    });
                }
    
                // Add this point to the current line.
                lines[lines.length - 1].points.push(pt);
    
                // Cache the classes for the next loop iteration.
                lastClasses = lineClasses;
    
    module.exports = { pointsSelector, lineSegmentsSelector, isVisibleSelector, MASK_DESC };