Commit 633433df authored by 涂茜's avatar 涂茜

feat: 查看历史数据组件

parent 100e61e7
Pipeline #24726 failed with stages
in 8 seconds
......@@ -107,7 +107,7 @@ export default {
},
{
title: '数据展示',
children: ['DeviceTree', 'RealTimeInfo'],
children: ['DeviceTree', 'RealTimeInfo', 'HistoryInfo'],
},
],
},
......
......@@ -130,6 +130,8 @@
"@wisdom-components/Empty": "^1.0.1",
"classnames": "^2.2.6",
"cross-spawn": "^7.0.3",
"highcharts": "^9.0.1",
"highcharts-react-official": "^3.0.0",
"mqtt-client": "^1.0.11"
}
}
# `@wisdom-components/HistoryInfo`
> TODO: description
## Usage
```
const historyinfo = require('@wisdom-components/HistoryInfo');
// TODO: DEMONSTRATE API
```
{
"name": "@wisdom-components/historyinfo",
"version": "1.0.1",
"description": "> TODO: description",
"author": "tuqian <webtuqian@163.com>",
"homepage": "",
"license": "ISC",
"main": "lib/index.js",
"directories": {
"lib": "lib",
"test": "__tests__"
},
"files": [
"lib"
],
"publishConfig": {
"registry": "https://g.civnet.cn:4873/"
},
"repository": {
"type": "git",
"url": "https://g.civnet.cn:8443/ReactWeb5/wisdom-components.git"
},
"scripts": {
"test": "echo \"Error: run tests from root\" && exit 1"
}
}
---
title: HistoryInfo - 历史数据查看
nav:
title: 组件
path: /components
group:
path: /
---
# HistoryInfo 历史数据查看
基础业务组件
- 查看任意时间段的历史数据
- 允许同期对比任意历史数据
- 允许过滤异常值
- 允许指定时间间隔的数据抽稀
## 何时使用
- 以图表或表格形式,查看历史数据时。
## 代码演示
<code src="./demos/Basic.js">
## API
api 参考 Antd Table 组件 https://ant.design/components/table-cn/#API
| 参数 | 说明 | 类型 | 默认值 |
| ------------ | ---------------------------------------------- | ------------------ | -------- |
| title | 标题 | string | 指标曲线 |
| columns | 表格列的配置描述 | array | [ ] |
| dataSource | 表格数据源 | array | [ ] |
| tableProps | 表格其他 props | object | { } |
| chartOptions | 曲线的 options | object | { } |
| onChange | 选择时间设置或曲线设置的回调,会返回修改后的值 | function(value){ } | - |
import React, { useEffect, useState } from 'react';
import request from 'umi-request';
import moment from 'moment';
import HistoryInfo from '../index';
const Demo = () => {
const [data, setData] = useState([]);
const [series, setSeries] = useState([]);
const [columns, setColumns] = useState([
{
title: '采集时间',
dataIndex: 'time',
key: 'time',
},
]);
useEffect(() => {
fetchData(initialParams);
}, []);
const fetchData = (params = {}) => {
request(baseUrl + '/Publish/Monitor/Device/SensorsDataForStation', {
method: 'post',
data: params,
}).then((res) => {
let resData = response.data;
let columnsData = resData.map((item, index) => {
return {
title: `${item.EquipmentName}-${item.sensorName}${
item.unit ? '(' + item.unit + ')' : ''
}`,
dataIndex: `value${index + 1}`,
key: `value${index + 1}`,
};
});
let tableData = resData[0].dataModel.map((item, index) => ({ key: index, time: item.PT }));
tableData.forEach((item, i) => {
resData.forEach((child, index) => {
child.dataModel.forEach((value, j) => {
if (i === j) item[`value${index + 1}`] = value.PV;
});
});
});
setData(tableData);
setColumns([...columns, ...columnsData]);
handleSeries();
});
};
const handleSeries = () => {
let resData = response.data;
let seriesData = [];
resData.forEach((item) => {
let data = [];
let obj = {};
obj.name = item.EquipmentName + item.sensorName;
item.dataModel.forEach((child) => {
data.push({
x: moment(child.PT).valueOf(),
y: child.PV,
});
});
obj.data = data;
seriesData.push(obj);
});
setSeries(seriesData);
};
const onChangeParams = (value = []) => {
let params = initialParams;
const { dateRange, ignoreOutliers, zoom, unit } = value;
let requestArr = [];
dateRange.forEach((item) => {
let param = {
...params,
stream: params.stream.map((child) => ({
...child,
dateFrom: item.dateFrom,
dateTo: item.dateTo,
})),
ignoreOutliers,
zoom,
unit,
};
requestArr.push(fetchData(param));
});
Promise.all(requestArr).then((values) => {
console.log(values);
});
};
return (
<HistoryInfo
title={'指标曲线'}
columns={columns}
dataSource={data}
chartOptions={{ series }}
tableProps={{ bordered: true }}
onChange={onChangeParams}
/>
);
};
export default Demo;
const baseUrl = 'http://192.168.10.150:8777';
const initialParams = {
stream: [
{
stationCode: 'EGBF00000006',
sensors: '出水瞬时流量,今日供水量,今日用电量',
pointVersions: '二供泵房',
dateFrom: '2021-03-15 16:01:21',
dateTo: '2021-03-16 16:01:21',
},
{
stationCode: 'EGJZ00007117',
sensors: '进水压力,出水压力,泵1状态',
pointVersions: '二供机组',
dateFrom: '2021-03-15 16:01:21',
dateTo: '2021-03-16 16:01:21',
},
],
ignoreOutliers: false, // 过滤异常值
isVertical: false, // 是否展示竖表
zoom: '', // 数据抽稀
unit: '', // 数据抽稀 min h
};
const response = {
code: 0,
msg: 'Ok',
data: [
{
stationCode: 'EGBF00000006',
sensorName: '出水瞬时流量',
dataModel: [
{
PV: 8.38,
PT: '2021-03-15 16:03:49',
},
{
PV: 8.67,
PT: '2021-03-15 16:08:50',
},
{
PV: 9.32,
PT: '2021-03-15 16:18:21',
},
{
PV: 9.65,
PT: '2021-03-15 16:23:23',
},
{
PV: 9.63,
PT: '2021-03-15 16:28:24',
},
],
decimalPoint: 2,
EquipmentName: '温州嵇师村低压区智慧集成泵房',
unit: 'm³/h',
normalData: [],
dataModelAbnormal: [],
alarmHisList: [],
AreaCode: null,
SensorType: null,
Min_Data: null,
Avg_Data: null,
MinDatas: [],
MaxDatas: [],
},
{
stationCode: 'EGBF00000006',
sensorName: '今日供水量',
dataModel: [
{
PV: 179,
PT: '2021-03-15 16:03:49',
},
{
PV: 179,
PT: '2021-03-15 16:08:50',
},
{
PV: 181,
PT: '2021-03-15 16:18:21',
},
{
PV: 182,
PT: '2021-03-15 16:23:23',
},
{
PV: 182,
PT: '2021-03-15 16:28:24',
},
],
decimalPoint: 2,
EquipmentName: '温州嵇师村低压区智慧集成泵房',
unit: 'm³',
normalData: [],
dataModelAbnormal: [],
alarmHisList: [],
AreaCode: null,
SensorType: null,
Min_Data: null,
Avg_Data: null,
MinDatas: [],
MaxDatas: [],
},
{
stationCode: 'EGBF00000006',
sensorName: '今日用电量',
dataModel: [
{
PV: 34,
PT: '2021-03-15 16:03:49',
},
{
PV: 34,
PT: '2021-03-15 16:08:50',
},
{
PV: 35,
PT: '2021-03-15 16:18:21',
},
{
PV: 35,
PT: '2021-03-15 16:23:23',
},
{
PV: 35,
PT: '2021-03-15 16:28:24',
},
],
decimalPoint: 0,
EquipmentName: '温州嵇师村低压区智慧集成泵房',
unit: 'kWh',
normalData: [],
dataModelAbnormal: [],
alarmHisList: [],
AreaCode: null,
SensorType: null,
Min_Data: null,
Avg_Data: null,
MinDatas: [],
MaxDatas: [],
},
{
stationCode: 'EGJZ00007117',
sensorName: '进水压力',
dataModel: [
{
PV: 0.08,
PT: '2021-03-15 16:04:21',
},
{
PV: 0.09,
PT: '2021-03-15 16:09:22',
},
{
PV: 0.09,
PT: '2021-03-15 16:18:21',
},
{
PV: 0.08,
PT: '2021-03-15 16:23:23',
},
{
PV: 0.08,
PT: '2021-03-15 16:28:24',
},
],
decimalPoint: 2,
EquipmentName: '温州嵇师村低压区智慧集成泵房-低区',
unit: 'MPa',
normalData: [],
dataModelAbnormal: [],
alarmHisList: [],
AreaCode: null,
SensorType: null,
Min_Data: null,
Avg_Data: null,
MinDatas: [],
MaxDatas: [],
},
{
stationCode: 'EGJZ00007117',
sensorName: '出水压力',
dataModel: [
{
PV: 0.33,
PT: '2021-03-15 16:04:21',
},
{
PV: 0.34,
PT: '2021-03-15 16:09:22',
},
{
PV: 0.33,
PT: '2021-03-15 16:18:21',
},
{
PV: 0.32,
PT: '2021-03-15 16:23:23',
},
{
PV: 0.32,
PT: '2021-03-15 16:28:24',
},
],
decimalPoint: 2,
EquipmentName: '温州嵇师村低压区智慧集成泵房-低区',
unit: 'MPa',
normalData: [],
dataModelAbnormal: [],
alarmHisList: [],
AreaCode: null,
SensorType: null,
Min_Data: null,
Avg_Data: null,
MinDatas: [],
MaxDatas: [],
},
{
stationCode: 'EGJZ00007117',
sensorName: '泵1状态',
dataModel: [
{
PV: 1,
PT: '2021-03-15 16:04:21',
},
{
PV: 1,
PT: '2021-03-15 16:09:22',
},
{
PV: 1,
PT: '2021-03-15 16:18:21',
},
{
PV: 1,
PT: '2021-03-15 16:23:23',
},
{
PV: 1,
PT: '2021-03-15 16:28:24',
},
],
decimalPoint: 0,
EquipmentName: '温州嵇师村低压区智慧集成泵房-低区',
unit: null,
normalData: [],
dataModelAbnormal: [],
alarmHisList: [],
AreaCode: null,
SensorType: null,
Min_Data: null,
Avg_Data: null,
MinDatas: [],
MaxDatas: [],
},
],
};
This diff is collapsed.
@import (reference) '~antd/es/style/themes/default';
@history-info-prefix-cls: ~'@{ant-prefix}-history-info';
.@{history-info-prefix-cls} {
&-content {
padding: 10px 0 0 0;
}
&-time {
display: flex;
align-items: center;
white-space: nowrap;
margin-bottom: 20px;
.@{history-info-prefix-cls}-label {
letter-spacing: 27px;
}
.@{history-info-prefix-cls}-label:after {
right: -20px;
}
.ant-radio-group,
.ant-select {
margin-right: 16px;
}
.anticon-plus-circle {
margin-left: 10px;
font-size: 16px;
color: @primary-color;
cursor: pointer;
}
}
&-cover {
display: flex;
align-items: center;
white-space: nowrap;
margin-bottom: 20px;
}
&-label {
position: relative;
width: 80px;
}
&-label:after {
content: ':';
position: absolute;
right: 7px;
top: 0;
}
&-connect {
margin: 0 10px;
}
&-connect.first {
display: none;
}
&-contrast-list {
display: flex;
align-items: center;
}
}
......@@ -27,11 +27,12 @@ group:
自定义时间选择 api 参考 Antd DatePicker 组件 https://ant.design/components/date-picker-cn/#API
| 参数 | 说明 | 类型 | 默认值 |
| ----------- | ------------------------------------- | ------------------ | --------------------- |
| layout | 布局 | string | horizontal / vertical |
| placeholder | layout 值为 vertical 时,下拉框占位符 | string | 请选择 |
| width | layout 值为 vertical 时,下拉框宽度 | number | 120 |
| dataSource | 数据源 | array | - |
| timeProps | 自定义时间选择 api | object | { } |
| onChange | 选择事件的回调,会返回选中的时间项 | function(value){ } | - |
| 参数 | 说明 | 类型 | 默认值 |
| ------------ | ----------------------------------- | ------------------ | --------------------- |
| layout | 布局 | string | horizontal / vertical |
| value | 值 | string | - |
| defaultValue | 默认选中的值 | string | - |
| width | layout 值为 vertical 时,下拉框宽度 | number | 120 |
| dataSource | 数据源 | array | - |
| timeProps | 自定义时间选择 api | object | { } |
| onChange | 选择事件的回调,会返回选中的时间项 | function(value){ } | - |
......@@ -3,12 +3,12 @@ import TimeRangePicker from '../index';
import moment from 'moment';
const Demo = () => {
const [value, setValue] = useState('全部');
const [dateValue, setDateValue] = useState(null);
const [timeValue, setTimeValue] = useState(null);
const [data, setData] = useState({ startDate: '', endDate: '' });
const [time, setTime] = useState({ startTime: '', endTime: '' });
const onDateChange = (key, data = []) => {
let curData = dateList.filter((item) => item.key === key);
let start = '',
end = '';
switch (key) {
......@@ -65,12 +65,11 @@ const Demo = () => {
}
break;
}
setValue(curData[0].name);
setDateValue(key);
setData({ startDate: start, endDate: end });
};
const onTimeChange = (key, data = []) => {
let curData = timeList.filter((item) => item.key === key);
let start = '',
end = '';
switch (key) {
......@@ -101,17 +100,29 @@ const Demo = () => {
}
break;
}
setValue(curData[0].name);
setTimeValue(key);
setTime({ startTime: start, endTime: end });
};
return (
<>
<h3>horizontal</h3>
<TimeRangePicker onChange={onDateChange} dataSource={dateList} layout={'horizontal'} />
<TimeRangePicker
value={dateValue}
onChange={onDateChange}
defaultValue={dateList[0].key}
dataSource={dateList}
layout={'horizontal'}
/>
<br />
<h3>vertical</h3>
<TimeRangePicker onChange={onDateChange} dataSource={dateList} layout={'vertical'} />
<TimeRangePicker
value={dateValue}
onChange={onDateChange}
defaultValue={dateList[0].key}
dataSource={dateList}
layout={'vertical'}
/>
<br />
<div>
startDate{data.startDate}
......@@ -120,6 +131,7 @@ const Demo = () => {
</div>
<br />
<TimeRangePicker
value={timeValue}
onChange={onTimeChange}
dataSource={timeList}
timeProps={{ showTime: true }}
......
......@@ -8,7 +8,15 @@ import './index.less';
const { RangePicker } = DatePicker;
const { Option } = Select;
const TimeRangePicker = ({ layout, placeholder, width, dataSource, timeProps, onChange }) => {
const TimeRangePicker = ({
layout,
value,
defaultValue,
width,
dataSource,
timeProps,
onChange,
}) => {
const [visible, setVisible] = useState(false);
const [visibleKey, setVisibleKey] = useState(null);
......@@ -36,7 +44,7 @@ const TimeRangePicker = ({ layout, placeholder, width, dataSource, timeProps, on
const renderHorizontal = () => {
return (
<Radio.Group onChange={onRadioChange}>
<Radio.Group value={value} defaultValue={defaultValue} onChange={onRadioChange}>
{dataSource.map((item) => (
<Radio.Button key={item.key} value={item.key}>
{item.name}
......@@ -48,7 +56,12 @@ const TimeRangePicker = ({ layout, placeholder, width, dataSource, timeProps, on
const renderVertical = () => {
return !!dataSource.length ? (
<Select placeholder={placeholder} style={{ width: width }} onChange={onSelectChange}>
<Select
value={value}
defaultValue={defaultValue}
style={{ width: width }}
onChange={onSelectChange}
>
{dataSource.map((item) => (
<Option key={item.key} value={item.key}>
{item.name}
......@@ -85,7 +98,8 @@ const TimeRangePicker = ({ layout, placeholder, width, dataSource, timeProps, on
TimeRangePicker.defaultProps = {
layout: 'horizontal',
placeholder: '请选择',
value: '',
defaultValue: '',
width: 120,
dataSource: [],
timeProps: {},
......@@ -94,7 +108,8 @@ TimeRangePicker.defaultProps = {
TimeRangePicker.propTypes = {
layout: PropTypes.string,
placeholder: PropTypes.string,
value: PropTypes.string,
defaultValue: PropTypes.string,
width: PropTypes.number,
dataSource: PropTypes.array,
timeProps: PropTypes.object,
......
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