mobile.js 7.34 KB
Newer Older
陈龙's avatar
陈龙 committed
1 2
import React, {useEffect, useMemo, useState, useContext} from 'react';
import {ConfigProvider} from "antd";
陈龙's avatar
陈龙 committed
3
import {Selector, Checkbox, Space} from 'antd-mobile/es';
陈龙's avatar
陈龙 committed
4 5
import moment from "moment";
import {getDeviceAlarmScheme, getHistoryInfo} from "./apis";
6
import SingleChart from "./SingleChart";
陈龙's avatar
陈龙 committed
7 8
import {handlePx} from "./utils";
import styles from './index.less';
陈龙's avatar
陈龙 committed
9

陈龙's avatar
陈龙 committed
10
const DATE_FORMAT = 'YYYY-MM-DD HH:mm:ss';
陈龙's avatar
陈龙 committed
11 12
const MobileHistoryChart = (
    {
陈龙's avatar
陈龙 committed
13
        date, // 不传默认当天
陈龙's avatar
陈龙 committed
14
        deviceParams = [],  // 设备参数,必传
陈龙's avatar
陈龙 committed
15 16
        chartType = 'lineChart', // lineChart boxChart
        // ignoreOutliers = true, // 滤波
陈龙's avatar
陈龙 committed
17 18 19 20
        isDilute = true,  // 抽稀去重
        needMarkLine = true,
        showBoxOption = true, // 开启箱线图配置,默认开启
        chartGrid = true, // 开启网格
陈龙's avatar
陈龙 committed
21
        ...rest
陈龙's avatar
陈龙 committed
22 23 24 25
    }
) => {
    const [deviceAlarmSchemes, setDeviceAlarmSchemes] = useState(null);
    const [chartDataSource, setChartDataSource] = useState(null);
陈龙's avatar
陈龙 committed
26 27 28 29
    const [options, setOptions] = useState({
        curveCenter: true,
        ignoreOutliers: true
    });
陈龙's avatar
陈龙 committed
30 31 32 33 34
    const checkboxStyle = {
        '--icon-size': handlePx(18, 'px'),
        '--font-size': handlePx(14, 'px'),
        '--gap': handlePx(6, 'px'),
    }
陈龙's avatar
陈龙 committed
35 36 37 38 39 40 41
    const checkBoxOptions = useMemo(() => {
        return Object.keys(options).reduce((final, cur) => {
            if (options[cur]) final.push(cur);
            return final
        }, []);
    }, [options]);
    const [lineType, setLineType] = useState([chartType]);
陈龙's avatar
陈龙 committed
42 43 44
    const {getPrefixCls} = useContext(ConfigProvider.ConfigContext);
    const prefixCls = getPrefixCls('history-view');
    const isBoxPlots =
45
        deviceParams?.length === 1 && deviceParams?.[0]?.sensors?.split(',').length === 1;
陈龙's avatar
陈龙 committed
46
    const handleDataThinKey = (diffDays) => {
陈龙's avatar
陈龙 committed
47
        // 移动端缩放的抽稀一倍,需要实际调试
陈龙's avatar
陈龙 committed
48 49 50 51 52 53 54 55 56 57 58
        if (diffDays >= 7 && diffDays < 15) {
            return {unit: 'h', zoom: '4'};
        } else if (diffDays >= 15 && diffDays < 30) {
            return {unit: 'h', zoom: '8'};
        } else if (diffDays >= 30) {
            return {unit: 'h', zoom: '12'};
        } else if (diffDays < 7 && diffDays >= 2) {
            return {unit: 'min', zoom: '80'};
        } else if (diffDays < 2 && diffDays >= 1) {
            return {unit: 'min', zoom: '60'};
        } else {
陈龙's avatar
陈龙 committed
59
            return {unit: 'min', zoom: '60'};
陈龙's avatar
陈龙 committed
60 61 62 63
        }
    };

    const getDataSource = () => {
陈龙's avatar
陈龙 committed
64 65 66
        let dateFrom = date?.dateFrom || moment().subtract(1, 'days').format(`${DATE_FORMAT}`),
            dateTo = date?.dateTo || moment().format(`${DATE_FORMAT}`);
        let diffDays = moment(dateTo).diff(moment(dateFrom), 'days');
陈龙's avatar
陈龙 committed
67 68 69 70 71 72 73 74 75 76
        const thinKey = handleDataThinKey(diffDays);
        const acrossTables = deviceParams.map(item => {
            let _item = {...item};
            let _sensorArr = _item.sensors.split(',');
            if (!_sensorArr.includes('是否在线')) {
                _sensorArr.push('是否在线')
            }
            return _item;
        });
        let _params = {
陈龙's avatar
陈龙 committed
77 78
            dateFrom,
            dateTo,
陈龙's avatar
陈龙 committed
79
            isBoxPlots,
陈龙's avatar
陈龙 committed
80
            ignoreOutliers: options.ignoreOutliers,
陈龙's avatar
陈龙 committed
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132
            isDilute,
            ...thinKey,
            acrossTables
        };
        getHistoryInfo({..._params}).then(res => {
            let data = [];
            if (res.code === 0 && res.data.length) {
                res.data.forEach((d) => {
                    d.dateFrom = dateFrom || '';
                    d.dateTo = dateTo || '';
                });
                deviceParams.forEach((p) => {
                    // 返回数据按查询指标顺序排序
                    const sensors = p.sensors?.split(',') ?? [];
                    const list = sensors.map((s) => {
                        const dataItem = res.data.find(
                            (d) => d.stationCode === p.deviceCode && d.sensorName === s,
                        );
                        if (dataItem) {
                            dataItem.dateFrom = dateFrom || '';
                            dataItem.dateTo = dateTo || '';
                            return dataItem;
                        } else {
                            return {};
                        }
                    });
                    data = data.concat(list);
                });
            }
            setChartDataSource(data);
        })
    };
    const getScheme = () => {
        getDeviceAlarmScheme({
            data: deviceParams.map((item) => ({
                deviceType: item.deviceType,
                deviceCode: item.deviceCode,
                pointAddressID: item.pointAddressID,
                sensorName: item.sensors,
            })),
        }).then((res) => {
            if (res.code === 0) setDeviceAlarmSchemes(res.data || []);
            else setDeviceAlarmSchemes([]);
            return Promise.resolve();
        }).catch((err) => {
            setDeviceAlarmSchemes([]);
            return Promise.resolve();
        });
    }
    useEffect(() => {
        getScheme();
    }, [])
陈龙's avatar
陈龙 committed
133 134
    useEffect(() => {
        getDataSource();
陈龙's avatar
陈龙 committed
135
    }, [options.ignoreOutliers, date])
陈龙's avatar
陈龙 committed
136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164
    return deviceAlarmSchemes && chartDataSource ?
        <div style={{width: '100%', height: '100%', display: 'flex', flexDirection: 'column'}}>
            {
                chartDataSource.length === 1 ? <div className={styles[`${prefixCls}-item`]}>
                    <span style={{fontSize: handlePx(14)}}>曲线形态:</span>
                    <Selector
                        style={{display: 'inline-block', fontSize: handlePx(14)}}
                        options={[
                            {label: '线形图', value: 'lineChart'},
                            {label: '箱线图', value: 'boxChart'}
                        ]}
                        defaultValue={lineType}
                        onChange={(arr, extend) => {
                            setLineType(arr)
                        }}
                    />
                </div> : ''
            }
            <div className={styles[`${prefixCls}-item`]}>
                <span style={{fontSize: handlePx(14)}}>曲线设置:</span>
                <Checkbox.Group
                    value={checkBoxOptions}
                    onChange={val => {
                        let _arr = Object.keys(options);
                        let _options = _arr.reduce((final, cur) => {
                            final[cur] = !!val.includes(cur);
                            return final;
                        }, {})
                        setOptions(_options);
陈龙's avatar
陈龙 committed
165
                    }}
陈龙's avatar
陈龙 committed
166 167 168 169 170 171 172 173
                >
                    <Space direction='horizontal'>
                        <Checkbox style={checkboxStyle} value='curveCenter'>曲线居中</Checkbox>
                        <Checkbox style={checkboxStyle} value='ignoreOutliers'>滤波</Checkbox>
                    </Space>
                </Checkbox.Group>
            </div>
            <div style={{width: '100%', flex: 1}}>
174
                <SingleChart
陈龙's avatar
陈龙 committed
175 176 177 178 179 180 181
                    showBoxOption={showBoxOption}
                    curveCenter={options.curveCenter}
                    showGridLine={chartGrid}
                    prefixCls={prefixCls}
                    dataSource={chartDataSource}
                    chartType={isBoxPlots ? lineType[0] : null}
                    deviceAlarmSchemes={deviceAlarmSchemes}
陈龙's avatar
陈龙 committed
182
                />
陈龙's avatar
陈龙 committed
183 184
            </div>
        </div> : null
陈龙's avatar
陈龙 committed
185 186 187 188
}
export {
    MobileHistoryChart
}