Commit d920b3f2 authored by 陈龙's avatar 陈龙

feat: 调整历史曲线

parent df570e92
......@@ -3,13 +3,13 @@ import HistoryView from '../index';
import {MobileHistoryChart} from "../mobile";
const deviceParams = [
{
deviceCode: 'EGBF00000141',
// sensors: '进水压力,出水瞬时流量,出水累计流量',
sensors: '进水压力',
deviceType: '二供泵房',
pointAddressID: 208,
},
/* {
deviceCode: 'EGBF00000141',
// sensors: '进水压力,出水瞬时流量,出水累计流量',
sensors: '进水压力',
deviceType: '二供泵房',
pointAddressID: 208,
},*/
/* {
"deviceCode": "SYJ00000008",
"sensors": "瞬时流量",
......@@ -32,28 +32,42 @@ const deviceParams = [
deviceType: '二供机组',
pointAddressID: 4,
},*/
/* {
"deviceCode": "LLJ00000055",
"sensors": "正累计流量,瞬时流量,是否在线",
"deviceType": "流量计"
}*/
/* {
"deviceCode": "LLJ00000055",
"sensors": "正累计流量,瞬时流量,是否在线",
"deviceType": "流量计"
}*/
/* {
"deviceCode": "EGJZ00000163",
"sensors": "进水压力,是否在线",
"deviceType": "二供机组"
}*/
// 邳州张楼水厂
/* {
"deviceCode": "SC00000023",
"sensors": "出水压力",
"deviceType": "水厂"
}*/
/*
{
"deviceCode": "JFJ00000001",
"sensors": "沉淀池投矾量瞬时,",
"deviceType": "加矾间"
}*/
/* {
"deviceCode": "SC00000023",
"sensors": "出水压力",
"deviceType": "水厂"
}*/
/* {
"deviceCode": "JFJ00000001",
"sensors": "沉淀池投矾量瞬时,",
"deviceType": "加矾间"
}*/
/* {
"deviceCode": "QSBF00000001",
"sensors": "取水浊度",
"deviceType": "取水泵房"
}*/
/* {
"deviceCode": "SC00000023",
"sensors": "出水瞬时流量,是否在线",
"deviceType": "水厂"
}*/
{
"deviceCode": "XNCDC00000001",
"sensors": "沉淀池1号进水管流量",
"deviceType": "絮凝沉淀池"
}
];
const Demo = () => {
return (
......
import React, {useContext, useEffect, useMemo, useState, useCallback} from 'react';
import React, {useContext, useEffect, useMemo, useState, useCallback, useRef} from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import {
......@@ -11,7 +11,7 @@ import {
Tabs,
Tooltip,
Button,
message,
message, Progress,
} from 'antd';
import {
CloseCircleFilled,
......@@ -47,6 +47,10 @@ const timeList = [
key: 'roundClock',
name: '近24小时',
},
{
key: 'yesterday',
name: '昨日'
},
{
key: 'oneWeek',
name: '近1周',
......@@ -111,6 +115,7 @@ const CheckboxData = [
showInCurve: true,
showInTable: true,
tooltip: '本算法采用递推平均滤波法(滑动平均滤波法)对采样数据进行均值化平滑处理。',
hasSub: true
},
{
key: 'dataThin',
......@@ -190,6 +195,10 @@ const updateTime = (key) => {
start = moment().subtract(24, 'hour').format(timeFormat);
end = moment().format(timeFormat);
break;
case 'yesterday':
start = moment().subtract(1, 'days').format('YYYY-MM-DD 00:00:00');
end = moment().subtract(1, 'days').format('YYYY-MM-DD 23:59:59');
break;
case 'oneWeek':
start = moment().subtract(7, 'day').format(timeFormat);
end = moment().format(timeFormat);
......@@ -244,8 +253,8 @@ const timeColumn = {
sorter: true,
// sortOrder:['descend','ascend']
};
const OriginMaxDays = 7; // 原始曲线请求数据的最大天数
const CharacteristicMaxDays = 60; // 特征曲线或者其他曲线的最大天数
const OriginMaxDays = 31; // 原始曲线请求数据的最大天数
const CharacteristicMaxDays = null; // 特征曲线或者其他曲线的最大天数
const HistoryView = (props) => {
const [completeInit, setCompleteInit] = useState(false);
const {getPrefixCls} = useContext(ConfigProvider.ConfigContext);
......@@ -279,6 +288,7 @@ const HistoryView = (props) => {
const [checkboxData, setCheckboxData] = useState(() => [...CheckboxData]); // 曲线设置项
const [dataThinKey, setDataThinKey] = useState(timeIntervalList[0].key); // 曲线抽稀时间设置
const [algorithmValue, setAlgorithmValue] = useState(1);
const [columns, setColumns] = useState([]);
const [tableData, setTableData] = useState([]);
......@@ -292,6 +302,7 @@ const HistoryView = (props) => {
// onShortcutsChange
const [shortcutsValue, setShortcutsValue] = useState('');
const [shortcutsDatePickerArr, setShortcutsDatePickerArr] = useState([]);
const [percent, setPercent] = useState(0);
// 选择的时间范围值
const dateRange = useMemo(() => {
if (timeValue === 'customer') {
......@@ -339,10 +350,10 @@ const HistoryView = (props) => {
// 自定义模式: 快速选择
const onCustomerTimeChange = (key) => {
if (key === 'oneMonth' && lineDataType === '原始曲线') {
setLineDataType('特征曲线');
message.info('月模式数据量较大,不支持原始曲线模式,已切换为特征曲线')
}
/* if (key === 'oneMonth' && lineDataType === '原始曲线') {
setLineDataType('特征曲线');
message.info('月模式数据量较大,不支持原始曲线模式,已切换为特征曲线')
}*/
setCustomerChecked(key);
!!customerTime && setCustomerTime(null);
};
......@@ -356,7 +367,7 @@ const HistoryView = (props) => {
} else {
setCustomerChecked(null);
let diffDays = moment(value[1]).diff(moment(value[0]), 'days');
if (diffDays > 7 && lineDataType === '原始曲线') {
if (diffDays > OriginMaxDays && lineDataType === '原始曲线') {
setLineDataType('特征曲线');
message.info('时间区间超过7天,已切换为特征曲线');
}
......@@ -493,10 +504,11 @@ const HistoryView = (props) => {
format={'YYYY-MM-DD HH:mm'}
onChange={onCustomerTimeChange}
value={customerChecked}
dataSource={timeList.filter(item => {
if (lineDataType === '原始曲线') return item.key !== 'oneMonth';
return true
})}
/* dataSource={timeList.filter(item => {
if (lineDataType === '原始曲线') return item.key !== 'oneMonth';
return true
})}*/
dataSource={timeList}
/>
<RangePicker
format={'YYYY-MM-DD HH:mm'}
......@@ -504,7 +516,6 @@ const HistoryView = (props) => {
onChange={onCustomerRangeChange}
value={dates || customerTime}
onCalendarChange={(val) => {
console.log('val: ', val);
setDates(val);
}}
onOpenChange={(open) => {
......@@ -520,6 +531,7 @@ const HistoryView = (props) => {
if (!dates) {
return false;
}
if (!_days) return false;
const tooLate = dates[0] && current.diff(dates[0], 'days') > _days;
const tooEarly = dates[1] && dates[1].diff(current, 'days') > _days;
return !!tooEarly || !!tooLate;
......@@ -533,16 +545,12 @@ const HistoryView = (props) => {
)}
{timeValue === 'contrast' && ( // 同期对比
<>
{
lineDataType !== '原始曲线' &&
<Select value={contrastOption} style={{width: 60}} onChange={onContrastChange}>
<Option value="day"></Option>
<Option value="month"></Option>
</Select>
}
<Select value={contrastOption} style={{width: 60}} onChange={onContrastChange}>
<Option value="day"></Option>
<Option value="month" disabled={lineDataType === '原始曲线'}></Option>
</Select>
{/*增加快捷日期*/}
{
lineDataType !== '原始曲线' &&
deviceParams?.length === 1 && deviceParams?.[0]?.sensors?.split(',').length === 1 ?
<Radio.Group value={shortcutsValue} onChange={onShortcutsChange}>
{
......@@ -624,9 +632,12 @@ const HistoryView = (props) => {
let _startDate = dateRange[0]?.dateFrom;
let _endDate = dateRange[0]?.dateTo;
let diffDays = moment(_endDate).diff(moment(_startDate), 'days');
if (_val === '原始曲线' && diffDays > 7) {
message.info('查阅原始曲线时,需选择小于或等于7天的时间间隔,已自动切换为近一周');
setCustomerChecked('oneWeek');
if (_val === '原始曲线' && diffDays > OriginMaxDays) {
message.info('查阅原始曲线时,需选择小于或等于31天的时间间隔,已自动切换为近一月');
setCustomerChecked('oneMonth');
}
if (_val === '原始曲线') {
setContrastOption('day');
}
setLineDataType(_val)
};
......@@ -647,6 +658,15 @@ const HistoryView = (props) => {
<QuestionCircleFilled className={`${prefixCls}-question`}/>
</Tooltip>
)}
{
child.hasSub && child.checked && false ?
<Select style={{width: 80, marginLeft: 10}} value={algorithmValue}
onChange={(e) => setAlgorithmValue(e)}>
<Option value={1}></Option>
<Option value={5}></Option>
<Option value={10}></Option>
</Select> : ''
}
</>
)
);
......@@ -670,7 +690,7 @@ const HistoryView = (props) => {
<Radio.Button value={'原始曲线'}>原始曲线</Radio.Button>
</Radio.Group>
{/*<Segmented value={lineDataType} options={['特征曲线', '原始曲线']} onChange={switchLineDataType}/>*/}
<Tooltip title={'原始曲线数据量较大,请查阅小于7天的数据~'}>
<Tooltip title={'原始曲线数据量较大,单次查询最多展示1万条数据'}>
<QuestionCircleFilled style={{marginLeft: 6}} className={`${prefixCls}-question`}/>
</Tooltip>
</div>
......@@ -929,6 +949,8 @@ const HistoryView = (props) => {
acrossTables,
isBoxPlots: isBoxPlots,
};
// if (ignoreOutliers) param.algorithmValue = algorithmValue;
param.algorithmValue = algorithmValue;
let diffYears = moment(item.dateTo).diff(moment(item.dateFrom), 'years');
let diffDays = moment(item.dateTo).diff(moment(item.dateFrom), 'days');
let diffHours = moment(item.dateTo).diff(moment(item.dateFrom), 'hours');
......@@ -994,7 +1016,7 @@ const HistoryView = (props) => {
isBoxPlots: isBoxPlots,
});
});
}, [dateRange, dataConfig, deviceParams, chartType, lineDataType, completeInit]);
}, [dateRange, dataConfig, deviceParams, chartType, lineDataType, completeInit, algorithmValue]);
const handleChange = (pagination, filter, sort) => {
if (sort.field === 'time') {
setTimeOrder(sort.order)
......@@ -1035,6 +1057,26 @@ const HistoryView = (props) => {
</div>
</>
}, [timeOrder, chartDataSource, columns, tableProps, tableData])
const returnLongestPeriod = (data) => {
let _earliest = ''
let _latest = '';
data.forEach(item => {
let _length = item.dataModel.length;
let _tempFirst = item.dataModel[0].pt;
let _tempLast = item.dataModel[_length - 1].pt;
if (_earliest) {
_earliest = moment(_earliest) > moment(_tempFirst) ? _tempFirst : _earliest
} else {
_earliest = _tempFirst
}
if (_latest) {
_latest = moment(_latest) < moment(_tempLast) ? _tempLast : _latest
} else {
_latest = _tempLast;
}
})
return `${_earliest} - ${_latest}`;
};
const renderPanel = (model) => {
if (model === 'curve') {
return (
......@@ -1046,6 +1088,10 @@ const HistoryView = (props) => {
deviceParams?.length === 1 && deviceParams?.[0]?.sensors?.split(',').length === 1,
)}
</div>
{
lineDataType === '原始曲线' ?
<div style={{marginTop: 10}}>展示区间:{returnLongestPeriod(chartDataSource)}</div> : ''
}
<div className={`${prefixCls}-content`}>
{!chartDataSource.length ? (
<PandaEmpty/>
......@@ -1108,9 +1154,37 @@ const HistoryView = (props) => {
useEffect(() => {
getDefaultOptions();
}, [])
let percentTimer = useRef({
timer: null
});
useEffect(() => {
if (loading) {
let _percent = percent;
percentTimer.current.timer = setInterval(() => {
_percent += 5;
if (_percent > 90) return clearInterval(percentTimer.current.timer);
setPercent(_percent);
}, 100)
} else {
clearInterval(percentTimer.current.timer);
setPercent(100);
setTimeout(() => {
setPercent(0);
}, 500)
}
}, [loading])
return (
<div className={classNames(prefixCls, 'wkt-scroll-light')}>
<Spin spinning={loading} wrapperClassName={classNames(`${prefixCls}-spin`)}>
{/*<Spin spinning={loading} wrapperClassName={classNames(`${prefixCls}-spin`)}>*/}
<div className={classNames(`${prefixCls}-spin`)} style={{position: "relative"}}>
{
loading || percent !== 0 ? <div className={classNames(`${prefixCls}-progressWrapper`)}>
<Progress percent={percent} steps={20}
className={classNames(`${prefixCls}-progress`, `${prefixCls}-blink-2`)}
showInfo={false}/>
<div className={classNames(`${prefixCls}-tip`)}>加载中。。</div>
</div> : ''
}
{showModels.length === 1 && (
<div className={`${prefixCls}-single-panel`}>{renderPanel(showModels[0])}</div>
)}
......@@ -1143,7 +1217,8 @@ const HistoryView = (props) => {
</Tabs.TabPane>
</Tabs>
)}
</Spin>
</div>
{/*</Spin>*/}
</div>
);
};
......
......@@ -38,6 +38,34 @@
height: 100%;
}
.@{history-view}-progressWrapper {
z-index: 100;
position: absolute;
top: 0;
left: 0;
height: 100%;
width: 100%;
background: rgba(255, 255, 255, 0.9);
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
.@{history-view}-progress {
display: inline-flex;
}
.@{history-view}-tip {
display: inline-block;
margin-top: 10px;
color: #1890ff;
}
}
.@{history-view}-progress {
}
.@{history-view}-single-panel {
display: flex;
flex-direction: column;
......@@ -205,3 +233,36 @@
align-items: center;
margin-bottom: 0.3rem;
}
.@{history-view}-blink-2 {
-webkit-animation: blink-2 10s infinite both;
animation: blink-2 10s infinite both;
}
/**
* ----------------------------------------
* animation blink-2
* ----------------------------------------
*/
@-webkit-keyframes blink-2 {
0% {
opacity: 1;
}
50% {
opacity: 0.4;
}
100% {
opacity: 1;
}
}
@keyframes blink-2 {
0% {
opacity: 1;
}
50% {
opacity: 0.4;
}
100% {
opacity: 1;
}
}
......@@ -546,7 +546,7 @@ const handleYAxis = ({dataSource, needUnit, curveCenter, showGridLine}) => {
const rightNum = Math.floor(yAxisMap.size / 2);
return {leftNum, rightNum, yAxis};
}
const assignOptions = (restOption, xAxis, legendData, chartType) => {
const assignOptions = (restOption, xAxis, legendData, chartType, contrast, contrastOption) => {
restOption.dataZoom = [
{
show: true,
......@@ -566,6 +566,14 @@ const assignOptions = (restOption, xAxis, legendData, chartType) => {
height: currentOption['dataZoomHeight'],
type: 'slider',
zoomOnMouseWheel: true,
labelFormatter: function (e) {
let _formatterStr = 'YYYY-MM-DD HH:mm:ss';
if (contrast) {
if (contrastOption === 'day') _formatterStr = 'HH:mm';
if (contrastOption === 'month') _formatterStr = 'MM月DD日 HH时';
}
return moment(e).format(_formatterStr)
}
},
];
xAxis.minInterval = 3600 * (1 * 1000);
......@@ -576,6 +584,12 @@ const assignOptions = (restOption, xAxis, legendData, chartType) => {
const returnMaxOrMinNumber = (dataSource, type) => {
let _obj = null;
if (type === 'period' && dataSource?.[0]?.dataModel?.length) {
let _length = dataSource?.[0]?.dataModel?.length;
let _first = dataSource?.[0]?.dataModel[0]?.pt;
let _last = dataSource?.[0]?.dataModel[_length - 1]?.pt;
return ['展示时段: ', _first, _last, type]
}
dataSource?.[0]?.dataModel.filter(item => item.pv !== null).forEach(item => {
if (!_obj) {
_obj = item;
......@@ -667,6 +681,7 @@ const renderItem = (params, api) => {
const returnCustomSeries = (dataSource) => {
let _maxNumber = returnMaxOrMinNumber(dataSource, 'max');
let _minNumber = returnMaxOrMinNumber(dataSource, 'min');
// let _period = returnMaxOrMinNumber(dataSource, 'period');
// 需要将最大值最小分别传入,后续计算图例位置需要,先min后max
let _max = _maxNumber[1];
let _min = _minNumber[1];
......@@ -813,13 +828,13 @@ const optionGenerator = (dataSource, cusOption, contrast, contrastOption, smooth
}</span>
<span style="font-size: ${handlePx(12, 'px')};">${_unit ?? ''}</span>
</div>
<div style="display: ${lineDataType==='特征曲线'?'flex':'none'}; align-items: center;">
<div style="display: ${lineDataType === '特征曲线' ? 'flex' : 'none'}; align-items: center;">
<span>周期最小值</span><span style="display:inline-block;">:</span>
<span style="color: ${COLOR.AVG};margin: 0 ${handlePx(5, 'px')} 0 auto;">${e?.[1]?.value?.[1] ?? '-'
}</span>
<span style="font-size: ${handlePx(12, 'px')};">${_unit ?? ''}</span>
</div>
<div style="display: ${lineDataType==='特征曲线'?'flex':'none'}; align-items: center;">
<div style="display: ${lineDataType === '特征曲线' ? 'flex' : 'none'}; align-items: center;">
<span>周期最大值</span><span style="display:inline-block;">:</span>
<span style="color: ${COLOR.AVG};margin: 0 ${handlePx(5, 'px')} 0 auto;">${_maxValues[e?.[2]?.dataIndex] ?? '-'
}</span>
......@@ -840,7 +855,7 @@ const optionGenerator = (dataSource, cusOption, contrast, contrastOption, smooth
}
tooltip.timeFormat = tooltipTimeFormat;
let _legendData = series.filter(item => !['周期最大值', '周期最小值', '自定义'].includes(item.name)).map(item => item.name);
assignOptions(restOption, xAxis, _legendData, chartType);
assignOptions(restOption, xAxis, _legendData, chartType, contrast, contrastOption);
return {
yAxis,
grid,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment