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: [],
},
],
};
import React, { useContext, useState, useReducer, useEffect } from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import Highcharts from 'highcharts/highstock';
import HighchartsReact from 'highcharts-react-official';
import { Tabs, Select, Radio, Checkbox, Table, ConfigProvider, DatePicker } from 'antd';
import { PlusCircleOutlined } from '@ant-design/icons';
import TimeRangePicker from '@wisdom-components/timerangepicker/src';
import Empty from '@wisdom-components/Empty';
import moment from 'moment';
import './index.less';
const { TabPane } = Tabs;
const { RangePicker } = DatePicker;
const { Option } = Select;
const reducer = (state, action) => {
switch (action.type) {
case 'updateTime':
return {
...state,
dateRange: updateTime(action.payload),
};
case 'updateBatchTime':
return {
...state,
dateRange: action.payload,
};
case 'updateIgnoreOutliers':
return {
...state,
ignoreOutliers: action.payload,
};
case 'updateDataThin':
const { zoom, unit } = action.payload;
return {
...state,
zoom,
unit,
};
default:
throw new Error();
}
};
const updateTime = (key) => {
let start = '',
end = '';
if (Array.isArray(key)) {
start = moment(key[0]).format(timeFormat);
end = moment(key[1]).format(timeFormat);
} else {
switch (key) {
case 'oneHour':
start = moment().subtract(1, 'hour').format(timeFormat);
end = moment().format(timeFormat);
break;
case 'fourHour':
start = moment().subtract(4, 'hour').format(timeFormat);
end = moment().format(timeFormat);
break;
case 'twelveHours':
start = moment().subtract(12, 'hour').format(timeFormat);
end = moment().format(timeFormat);
break;
case 'roundClock':
start = moment().subtract(24, 'hour').format(timeFormat);
end = moment().format(timeFormat);
break;
case 'yesterday':
start = moment().subtract(1, 'days').format(startFormat);
end = moment().subtract(1, 'days').format(endFormat);
break;
}
}
return [
{
dateFrom: start,
dateTo: end,
},
];
};
const unique = (arr) => {
let unique = {};
arr.forEach(function (item) {
unique[JSON.stringify(item)] = item;
});
arr = Object.keys(unique).map(function (v) {
return JSON.parse(v);
});
return arr;
};
const HistoryInfo = (props) => {
const { getPrefixCls } = useContext(ConfigProvider.ConfigContext);
const prefixCls = getPrefixCls('history-info');
const { title, columns, dataSource, tableProps, chartOptions, onChange } = props;
const [timeValue, setTimeValue] = useState('customer');
const [contrastOption, setContrastOption] = useState('day');
const [customerChecked, setCustomerChecked] = useState(null);
const [customerTime, setCustomerTime] = useState(null);
const [datePickerArr, setDatePickerArr] = useState(DataPickerArr);
const [checkboxData, setCheckboxData] = useState(CheckboxData);
const [dataThinKey, setDataThinKey] = useState(timeIntervalList[0].key);
const [state, dispatch] = useReducer(reducer, initialState);
useEffect(() => {
onChange(state);
}, [state]);
// 时间设置切换(自定义/同期对比)
const onTimeSetChange = (e) => {
setTimeValue(e.target.value);
};
// 选择(日/月)
const onContrastChange = (value) => {
setContrastOption(value);
handleBatchTime([...datePickerArr], value);
};
const onCustomerRangeChange = (value) => {
setCustomerTime(value);
dispatch({ type: 'updateTime', payload: value });
};
const onCustomerTimeChange = (key) => {
setCustomerChecked(key);
dispatch({ type: 'updateTime', payload: key });
};
const handleBatchTime = (arr, contrastOption) => {
let newArr = [];
arr.forEach((child) => {
if (child.value) {
newArr.push({
dateFrom: moment(child.value).startOf(contrastOption).format(startFormat),
dateTo: moment(child.value).endOf(contrastOption).format(endFormat),
});
}
});
newArr = unique(newArr);
dispatch({ type: 'updateBatchTime', payload: newArr });
};
const onContrastPickerChange = (date, dateString, item) => {
let arr = [...datePickerArr];
arr.forEach((child) => {
if (child.key === item.key) {
child.value = date;
}
});
handleBatchTime(arr, contrastOption);
};
//新增日期选择组件
const handleAddDatePicker = () => {
setDatePickerArr([
...datePickerArr,
{
key: datePickerArr.length + 1,
value: '',
},
]);
};
const onCheckboxChange = (e, key) => {
let data = [...checkboxData];
data.forEach((item) => {
if (item.key === key) {
item.checked = e.target.checked;
if (key === 'dataThin') {
if (e.target.checked) {
timeIntervalList.forEach((child) => {
if (child.key === dataThinKey) {
dispatch({ type: item.type, payload: { zoom: dataThinKey, unit: child.unit } });
}
});
} else {
dispatch({ type: item.type, payload: { zoom: '', unit: '' } });
}
}
if (key === 'ignoreOutliers') {
dispatch({ type: item.type, payload: e.target.checked });
}
}
});
setCheckboxData(data);
};
// 数据抽稀时间间隔
const onTimeIntervalChange = (value, { unit }) => {
let data = checkboxData.filter((item) => item.key === 'dataThin');
if (data[0].checked) {
dispatch({ type: 'updateDataThin', payload: { zoom: value, unit: unit } });
}
setDataThinKey(value);
};
const renderCheckbox = (child) => (
<Checkbox
value={child.key}
checked={child.checked}
onChange={(e) => onCheckboxChange(e, child.key)}
>
{child.label}
</Checkbox>
);
const renderOptions = (item) => {
return (
<>
<div className={classNames(`${prefixCls}-time`)}>
<div className={classNames(`${prefixCls}-label`)}>时间</div>
<Radio.Group defaultValue={timeValue} onChange={onTimeSetChange}>
<Radio.Button value="customer">自定义</Radio.Button>
<Radio.Button value="contrast">同期对比</Radio.Button>
</Radio.Group>
{timeValue === 'customer' && ( // 自定义
<>
<TimeRangePicker
onChange={onCustomerTimeChange}
value={customerChecked}
dataSource={timeList}
/>
<RangePicker
className={classNames(`${prefixCls}-customer`)}
onChange={onCustomerRangeChange}
value={customerTime}
showTime
/>
</>
)}
{timeValue === 'contrast' && ( // 同期对比
<>
<Select
defaultValue={contrastOption}
style={{ width: 60 }}
onChange={onContrastChange}
>
<Option value="day"></Option>
<Option value="month"></Option>
</Select>
{datePickerArr.map((child, index) => (
<div key={child.key} className={classNames(`${prefixCls}-contrast-list`)}>
<div className={classNames(`${prefixCls}-connect`, { first: child.key === 1 })}>
</div>
<DatePicker
picker={contrastOption}
value={child.value}
onChange={(date, dateString) => onContrastPickerChange(date, dateString, child)}
/>
</div>
))}
{datePickerArr.length < 5 && <PlusCircleOutlined onClick={handleAddDatePicker} />}
</>
)}
</div>
<div className={classNames(`${prefixCls}-cover`)}>
<div className={classNames(`${prefixCls}-label`)}>曲线设置</div>
{checkboxData.map((child) => (
<div key={child.key}>
{item.key === 'curve' && renderCheckbox(child)}
{item.key === 'table' && child.key !== 'curveCenter' && renderCheckbox(child)}
</div>
))}
<Select value={dataThinKey} style={{ width: 90 }} onChange={onTimeIntervalChange}>
{timeIntervalList.map((child) => (
<Option key={child.key} unit={child.unit} value={child.key}>
{child.name}
</Option>
))}
</Select>
</div>
</>
);
};
return (
<div className={classNames(prefixCls)}>
<Tabs
defaultActiveKey={TabPaneData[0].key}
centered
tabBarExtraContent={{
left: <h3 className="tabs-extra-demo-button">{title}</h3>,
}}
>
{TabPaneData.map((item) => (
<TabPane tab={item.tab} key={item.key}>
<div className={classNames(`${prefixCls}-content`)}>
{renderOptions(item)}
{!dataSource.length && <Empty />}
{!!dataSource.length && (
<div>
{item.key === 'curve' && (
<HighchartsReact
highcharts={Highcharts}
constructorType={'stockChart'}
options={{ ...defaultOptions, ...chartOptions }}
/>
)}
{item.key === 'table' && (
<Table dataSource={dataSource} columns={columns} {...tableProps} />
)}
</div>
)}
</div>
</TabPane>
))}
</Tabs>
</div>
);
};
HistoryInfo.defaultProps = {
title: '指标曲线',
columns: [],
dataSource: [],
tableProps: {},
chartOptions: {},
onChange: () => {},
};
HistoryInfo.propTypes = {
title: PropTypes.string,
columns: PropTypes.array,
dataSource: PropTypes.array,
tableProps: PropTypes.object,
chartOptions: PropTypes.object,
onChange: PropTypes.func,
};
export default HistoryInfo;
const startFormat = 'YYYY-MM-DD 00:00:00';
const endFormat = 'YYYY-MM-DD 23:59:59';
const timeFormat = 'YYYY-MM-DD kk:mm:ss';
const colors = [
'#1884EC',
'#90CE53',
'#86E0C7',
'#68cbd1',
'#bb98d1',
'#588c66',
'#b0859e',
'#647fac',
'#7c6894',
'#9c8273',
'#838b61',
'#437db0',
'#9b97c4',
'#bda589',
'#89bd8e',
'#cbcc75',
];
const defaultOptions = {
chart: {
type: 'area',
},
colors: colors,
title: null,
credits: false,
rangeSelector: {
enabled: false,
},
xAxis: {
labels: {
formatter: function () {
return moment(this.value).format('LT');
},
},
},
yAxis: {
title: null,
labels: {
formatter: function () {
return this.value;
},
},
scrollbar: {
enabled: true,
showFull: false,
},
},
tooltip: {
pointFormat: '<b>{series.name}-{point.y}</b>',
},
plotOptions: {
area: {
fillOpacity: 0.3, // 指定所有面积图的透明度
pointStart: 1940,
marker: {
enabled: false,
symbol: 'circle',
radius: 2,
states: {
hover: {
enabled: true,
},
},
},
},
},
legend: {
enabled: true,
verticalAlign: 'top',
},
series: [],
responsive: {
rules: [
{
condition: {
maxWidth: 800,
minHeight: 500,
},
},
],
},
};
const initialState = {
dateRange: [],
ignoreOutliers: false,
isVertical: false,
zoom: '',
unit: '',
};
const TabPaneData = [
{
key: 'curve',
tab: '曲线',
},
{
key: 'table',
tab: '表格',
},
];
const CheckboxData = [
{
key: 'curveCenter',
label: '曲线居中',
checked: false,
},
{
key: 'ignoreOutliers',
label: '过滤异常值',
type: 'updateIgnoreOutliers',
checked: false,
},
{
key: 'dataThin',
label: '数据抽稀',
type: 'updateDataThin',
checked: false,
},
];
const timeList = [
{
key: 'oneHour',
name: '近1小时',
},
{
key: 'fourHour',
name: '近4小时',
},
{
key: 'twelveHours',
name: '近12小时',
},
{
key: 'roundClock',
name: '近24小时',
},
{
key: 'yesterday',
name: '昨天',
},
];
const timeIntervalList = [
{
key: '5',
unit: 'min',
name: '5分钟',
},
{
key: '10',
unit: 'min',
name: '10分钟',
},
{
key: '30',
unit: 'min',
name: '30分钟',
},
{
key: '1',
unit: 'h',
name: '1小时',
},
{
key: '2',
unit: 'h',
name: '2小时',
},
{
key: '6',
unit: 'h',
name: '6小时',
},
{
key: '12',
unit: 'h',
name: '12小时',
},
];
const DataPickerArr = [
{
key: 1,
value: '',
},
{
key: 2,
value: '',
},
];
@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;
}
}
......@@ -28,9 +28,10 @@ group:
自定义时间选择 api 参考 Antd DatePicker 组件 https://ant.design/components/date-picker-cn/#API
| 参数 | 说明 | 类型 | 默认值 |
| ----------- | ------------------------------------- | ------------------ | --------------------- |
| ------------ | ----------------------------------- | ------------------ | --------------------- |
| layout | 布局 | string | horizontal / vertical |
| placeholder | layout 值为 vertical 时,下拉框占位符 | string | 请选择 |
| value | 值 | string | - |
| defaultValue | 默认选中的值 | string | - |
| width | layout 值为 vertical 时,下拉框宽度 | number | 120 |
| dataSource | 数据源 | array | - |
| timeProps | 自定义时间选择 api | object | { } |
......
......@@ -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