Commit a8144085 authored by 涂茜's avatar 涂茜

Merge branch 'feature/ec-components' into 'dev'

Feature/ec components See merge request !41
parents aaca1e10 6f5b036e
Pipeline #27886 failed with stages
in 5 minutes 17 seconds
...@@ -81,6 +81,7 @@ export default { ...@@ -81,6 +81,7 @@ export default {
{ {
title: '通用', title: '通用',
children: [ children: [
'BasicChart',
'BasicTable', 'BasicTable',
'BasicTools', 'BasicTools',
'ImageSelect', 'ImageSelect',
......
...@@ -138,7 +138,7 @@ ...@@ -138,7 +138,7 @@
"registry": "https://g.civnet.cn:4873" "registry": "https://g.civnet.cn:4873"
}, },
"dependencies": { "dependencies": {
"@wisdom-components/basictable": "^1.5.5", "@wisdom-components/basictable": "^1.5.6",
"@wisdom-components/empty": "^1.3.9", "@wisdom-components/empty": "^1.3.9",
"@wisdom-components/timerangepicker": "^1.3.4", "@wisdom-components/timerangepicker": "^1.3.4",
"@wisdom-utils/utils": "0.0.46", "@wisdom-utils/utils": "0.0.46",
......
# Change Log
All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# 1.2.0 (2021-05-14)
### Features
- add basicchart ([7652990](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/commits/7652990b734c05378e8e863904bbb495cb63cec2))
# `@wisdom-components/basicchart`
> TODO: description
## Usage
```
import BasicChart from '@wisdom-components/basicchart';
// TODO: DEMONSTRATE API
```
{
"name": "@wisdom-components/basicchart",
"version": "1.2.0",
"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: BasicChart - 标准图表
nav:
title: 基础组件
path: /components
group:
path: /
---
# BasicChart 标准图表
基础组件
- 支持的图表类型有直线图、曲线图等 20 种图表,其中很多图表可以集成在同一个图形中形成混合图
## 何时使用
- 当需要展现图表时;
## 代码演示
### 常规使用
<code src="./demos/Basic.tsx">
## API
api 参考 highcharts 库 https://api.highcharts.com.cn/highcharts
| 参数 | 说明 | 类型 | 默认值 | 可选值 |
| --- | --- | --- | --- | --- |
| constructorType | 标题 | string | chart | - 'chart' 用于 Highcharts 图表 <br/> - 'stockChart' 用于 Highstock 图表 <br/> - 'mapChart' 用于 Highmaps 图表 <br/> - 'ganttChart' 用于甘特图 |
| chartOptions`必需` | Highcharts 图表配置对象 | object | { } | - |
import React from 'react';
import BasicChart from '../index';
const Demo = () => {
return (
<div>
<h3>折线图</h3>
<div style={{ height: '600px' }}>
<BasicChart chartOptions={chartOptions1} />
</div>
<h3 style={{ marginTop: '40px' }}>曲线面积图</h3>
<div style={{ height: '600px' }}>
<BasicChart chartOptions={chartOptions2} />
</div>
<h3 style={{ marginTop: '40px' }}>带滚动条曲线图</h3>
<div style={{ height: '600px' }}>
<BasicChart chartOptions={chartOptions3} constructorType={'stockChart'} />
</div>
</div>
);
};
export default Demo;
const chartOptions1 = {
// ...
series: [
{
name: '今日供水量',
color: '#1884EC',
data: [
[1620720173000, 122],
[1620720473000, 122],
[1620720773000, 122],
[1620721073000, 123],
[1620721373000, 123],
[1620721673000, 123],
[1620721973000, 124],
[1620722274000, 124],
[1620722724000, 125],
[1620723024000, 125],
[1620723324000, 125],
],
},
],
};
const chartOptions2 = {
// ...
series: [
{
type: 'areaspline',
name: '出水瞬时流量',
color: '#68cbd1',
data: [
[1620720173000, 1.85],
[1620720473000, 8.22],
[1620720773000, 2.83],
[1620721073000, 2.62],
[1620721373000, 2.05],
[1620721673000, 8.7],
[1620721973000, 2.38],
[1620722274000, 3.31],
[1620722724000, 2.36],
[1620723024000, 2.98],
[1620723324000, 2.58],
],
marker: {
enabled: false,
},
},
],
plotOptions: {
areaspline: {
fillOpacity: 0.5,
},
},
};
const chartOptions3 = {
// ...
series: [
{
type: 'spline',
name: '进水压力',
color: '#1884EC',
data: [
[1620720173000, 0.08],
[1620720473000, 0.09],
[1620720773000, 0.09],
[1620721073000, 0.09],
[1620721373000, 0.09],
[1620721673000, 0.08],
[1620721973000, 0.09],
[1620722274000, 0.09],
[1620722724000, 0.09],
[1620723024000, 0.08],
[1620723324000, 0.08],
],
},
],
};
import React, { useContext, useEffect, useRef, useState } from 'react';
import classNames from 'classnames';
import PropTypes from 'prop-types';
import Highcharts from 'highcharts/highstock';
import HighchartsReact from 'highcharts-react-official';
import { ConfigProvider } from 'antd';
import './index.less';
let chartWidth = 0; // chart width
let chartHeight = 0; // chart height
const BasicChart = (props) => {
const { getPrefixCls } = useContext(ConfigProvider.ConfigContext);
const prefixCls = getPrefixCls('basic-chart');
const { chartOptions, constructorType } = props;
const [options, setOptions] = useState(defaultOptions);
const container = useRef(null);
// 处理图表options
const handleChartOptions = () => {
const options = {
...defaultOptions,
...chartOptions,
};
if (container.current) {
if (container.current.offsetWidth !== 0) {
chartWidth = container.current.offsetWidth;
chartHeight = container.current.offsetHeight;
}
Highcharts.setOptions({
// 处理 chart 高度坍塌
chart: {
width: container.current.offsetWidth === 0 ? chartWidth : container.current.offsetWidth,
height:
container.current.offsetHeight === 0 ? chartHeight : container.current.offsetHeight,
},
});
}
Highcharts.setOptions({
global: { timezoneOffset: -8 * 60 },
});
return options;
};
useEffect(() => {
setOptions({ ...handleChartOptions() });
}, [chartOptions]);
return (
<div className={classNames(prefixCls)} ref={container}>
<HighchartsReact
immutable={true}
highcharts={Highcharts}
constructorType={constructorType}
options={options}
{...props}
/>
</div>
);
};
BasicChart.defaultProps = {
constructorType: 'chart',
chartOptions: {},
};
BasicChart.propTypes = {
columns: PropTypes.string,
chartOptions: PropTypes.object,
};
export default BasicChart;
const defaultOptions = {
chart: {
zoomType: 'x',
backgroundColor: 'rgba(255, 255, 255, 0.5)',
},
title: null,
credits: false,
rangeSelector: {
enabled: false,
},
xAxis: [
{
lineWidth: 0,
crosshair: true,
type: 'datetime',
dateTimeLabelFormats: {
second: '%H:%M:%S',
minute: '%H:%M',
hour: '%H:%M',
day: '%d',
week: '%d',
month: '%d',
year: '%Y',
},
},
],
yAxis: [
{
title: null,
opposite: false, // 即坐标轴会显示在对立面
lineWidth: 1,
},
],
tooltip: {
shared: true,
split: false,
valueDecimals: 3,
dateTimeLabelFormats: {
second: '%H:%M:%S',
minute: '%H:%M',
hour: '%H:%M',
day: '%d',
week: '%d',
month: '%d',
year: '%Y',
},
},
plotOptions: {
series: {
showInNavigator: true,
connectNulls: false,
zoneAxis: 'x',
},
},
legend: {
verticalAlign: 'top',
},
series: [],
};
@import (reference) '../../../../node_modules/antd/es/style/themes/default';
@basic-chart-prefix-cls: ~'@{ant-prefix}-basic-chart';
.@{basic-chart-prefix-cls} {
width: 100%;
height: 100%;
}
...@@ -2,6 +2,12 @@ ...@@ -2,6 +2,12 @@
All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [1.4.0](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/compare/@wisdom-components/ec_devicetree@1.3.0...@wisdom-components/ec_devicetree@1.4.0) (2021-05-14)
### Features
- add basicchart ([7652990](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/commits/7652990b734c05378e8e863904bbb495cb63cec2))
# [1.3.0](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/compare/@wisdom-components/ec_devicetree@1.0.11...@wisdom-components/ec_devicetree@1.3.0) (2021-05-14) # [1.3.0](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/compare/@wisdom-components/ec_devicetree@1.0.11...@wisdom-components/ec_devicetree@1.3.0) (2021-05-14)
### Bug Fixes ### Bug Fixes
......
{ {
"name": "@wisdom-components/ec_devicetree", "name": "@wisdom-components/ec_devicetree",
"version": "1.3.0", "version": "1.4.0",
"description": "> TODO: description", "description": "> TODO: description",
"author": "tuqian <webtuqian@163.com>", "author": "tuqian <webtuqian@163.com>",
"homepage": "", "homepage": "",
......
import React, { useContext, useEffect, useState } from 'react'; import React, { useContext, useEffect, useState } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import classNames from 'classnames'; import classNames from 'classnames';
import { Input, Tree, Divider, message, Pagination, ConfigProvider } from 'antd'; import { Spin, Input, Tree, Divider, message, Pagination, ConfigProvider } from 'antd';
import { SearchOutlined } from '@ant-design/icons'; import { SearchOutlined } from '@ant-design/icons';
import Empty from '@wisdom-components/empty'; import Empty from '@wisdom-components/empty';
import './index.less'; import './index.less';
...@@ -23,6 +23,7 @@ const DeviceTree = (props) => { ...@@ -23,6 +23,7 @@ const DeviceTree = (props) => {
const [treeData, setTreeData] = useState([]); const [treeData, setTreeData] = useState([]);
const [params, setParams] = useState({}); const [params, setParams] = useState({});
const [total, setTotal] = useState(0); const [total, setTotal] = useState(0);
const [loading, setLoading] = useState(false);
useEffect(() => { useEffect(() => {
const param = { const param = {
...@@ -49,6 +50,7 @@ const DeviceTree = (props) => { ...@@ -49,6 +50,7 @@ const DeviceTree = (props) => {
}; };
const fetchData = (param = {}) => { const fetchData = (param = {}) => {
setLoading(true);
deviceTreeService(param).then((response) => { deviceTreeService(param).then((response) => {
if (response.code === 0) { if (response.code === 0) {
const data = response.data const data = response.data
...@@ -57,6 +59,7 @@ const DeviceTree = (props) => { ...@@ -57,6 +59,7 @@ const DeviceTree = (props) => {
: [] : []
: []; : [];
const newData = handleData(data); const newData = handleData(data);
setLoading(false);
setTreeData(newData); setTreeData(newData);
setTotal(response.data.totalPages); setTotal(response.data.totalPages);
onTreeCheck([newData[0]]); onTreeCheck([newData[0]]);
...@@ -104,7 +107,6 @@ const DeviceTree = (props) => { ...@@ -104,7 +107,6 @@ const DeviceTree = (props) => {
const onPaginationChange = (page) => { const onPaginationChange = (page) => {
setParams({ ...params, pageIndex: page }); setParams({ ...params, pageIndex: page });
setTreeData([]);
}; };
return ( return (
...@@ -118,10 +120,12 @@ const DeviceTree = (props) => { ...@@ -118,10 +120,12 @@ const DeviceTree = (props) => {
/> />
<Divider /> <Divider />
<div className={classNames(`${prefixCls}-content`)}> <div className={classNames(`${prefixCls}-content`)}>
<Spin spinning={loading}>
{!!treeData.length && ( {!!treeData.length && (
<Tree <Tree
defaultCheckedKeys={[treeData[0].key]} defaultCheckedKeys={[treeData[0].key]}
defaultExpandedKeys={[treeData[0].key]} defaultExpandedKeys={[treeData[0].key]}
defaultSelectedKeys={[treeData[0].key]}
treeData={treeData} treeData={treeData}
onCheck={onCheck} onCheck={onCheck}
onSelect={onSelect} onSelect={onSelect}
...@@ -129,7 +133,8 @@ const DeviceTree = (props) => { ...@@ -129,7 +133,8 @@ const DeviceTree = (props) => {
{...props} {...props}
/> />
)} )}
{!treeData.length && <Empty />} {!treeData.length && !loading && <Empty />}
</Spin>
</div> </div>
{pagination && ( {pagination && (
<div className={classNames(`${prefixCls}-pagination`)}> <div className={classNames(`${prefixCls}-pagination`)}>
......
...@@ -39,6 +39,10 @@ ...@@ -39,6 +39,10 @@
overflow-y: scroll; overflow-y: scroll;
} }
.ant-spin-nested-loading {
height: 100%;
}
&-pagination { &-pagination {
margin: 10px auto; margin: 10px auto;
} }
......
...@@ -212,7 +212,6 @@ const HistoryInfo = (props) => { ...@@ -212,7 +212,6 @@ const HistoryInfo = (props) => {
const [dataThinKey, setDataThinKey] = useState(timeIntervalList[0].key); const [dataThinKey, setDataThinKey] = useState(timeIntervalList[0].key);
const [options, setOptions] = useState({}); const [options, setOptions] = useState({});
const [colors, setColors] = useState(defaultColors); const [colors, setColors] = useState(defaultColors);
const [params, setParams] = useState(historyInfoParams);
const [tableData, setTableData] = useState([]); const [tableData, setTableData] = useState([]);
const [pageSize, setPageSize] = useState(20); const [pageSize, setPageSize] = useState(20);
const [series, setSeries] = useState([]); const [series, setSeries] = useState([]);
...@@ -237,9 +236,21 @@ const HistoryInfo = (props) => { ...@@ -237,9 +236,21 @@ const HistoryInfo = (props) => {
const seriesData = []; const seriesData = [];
resData.forEach((item) => { resData.forEach((item) => {
const data = []; const data = [];
if (item.dataModel.length) {
if (timeValue === 'contrast') {
// 同期对比
item.dataModel.forEach((child) => {
const formatTime = moment(child.pt).format(
contrastOption === 'day' ? '2020-01-01 HH:mm:00' : '2020-01-DD HH:mm:00',
);
data.push([moment(formatTime).valueOf(), child.pv]);
});
} else {
item.dataModel.forEach((child) => { item.dataModel.forEach((child) => {
data.push([moment(child.pt).valueOf(), child.pv]); data.push([moment(child.pt).valueOf(), child.pv]);
}); });
}
}
const obj = { const obj = {
name: item.equipmentName + '-' + item.sensorName, name: item.equipmentName + '-' + item.sensorName,
sensorName: item.sensorName, sensorName: item.sensorName,
...@@ -274,8 +285,11 @@ const HistoryInfo = (props) => { ...@@ -274,8 +285,11 @@ const HistoryInfo = (props) => {
// 处理采集时间 // 处理采集时间
resData.forEach((item) => { resData.forEach((item) => {
item.dataModel.forEach((data) => { item.dataModel.forEach((data) => {
if (!timeData.includes(data.pt)) { const formatTime = moment(data.pt).format(
timeData.push(data.pt); contrastOption === 'day' ? '2020-01-01 HH:mm:00' : '2020-01-DD HH:mm:00',
);
if (!timeData.includes(formatTime)) {
timeData.push(formatTime);
} }
}); });
}); });
...@@ -301,7 +315,10 @@ const HistoryInfo = (props) => { ...@@ -301,7 +315,10 @@ const HistoryInfo = (props) => {
tableData.forEach((item, i) => { tableData.forEach((item, i) => {
resData.forEach((child, index) => { resData.forEach((child, index) => {
child.dataModel.forEach((value, j) => { child.dataModel.forEach((value, j) => {
if (timeData[i] === value.pt) item[`value${index + 1}`] = value.pv; const formatTime = moment(value.pt).format(
contrastOption === 'day' ? '2020-01-01 HH:mm:00' : '2020-01-DD HH:mm:00',
);
if (timeData[i] === formatTime) item[`value${index + 1}`] = value.pv;
}); });
}); });
}); });
...@@ -315,8 +332,8 @@ const HistoryInfo = (props) => { ...@@ -315,8 +332,8 @@ const HistoryInfo = (props) => {
const requestArr = []; const requestArr = [];
dateRange.forEach((item) => { dateRange.forEach((item) => {
const param = { const param = {
...params, ...historyInfoParams,
stream: params.stream.map((child) => ({ stream: historyInfoParams.stream.map((child) => ({
...child, ...child,
dateFrom: item.dateFrom, dateFrom: item.dateFrom,
dateTo: item.dateTo, dateTo: item.dateTo,
......
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