Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wisdom-components
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
ReactWeb5
wisdom-components
Commits
365230d8
Commit
365230d8
authored
Oct 18, 2023
by
陈龙
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fix: 修复历史曲线频率、状态的图表显示异常
parent
4ea22fe6
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
462 additions
and
348 deletions
+462
-348
index.js
packages/extend-components/EC_HistoryView/src/index.js
+295
-214
utils.js
packages/extend-components/EC_HistoryView/src/utils.js
+167
-134
No files found.
packages/extend-components/EC_HistoryView/src/index.js
View file @
365230d8
import
React
,
{
useContext
,
useEffect
,
useMemo
,
useState
,
useCallback
,
useRef
}
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,8 @@ import {
Tabs
,
Tooltip
,
Button
,
message
,
Progress
,
message
,
Progress
,
}
from
'antd'
;
import
{
CloseCircleFilled
,
...
...
@@ -29,17 +30,18 @@ import {
getDeviceAlarmScheme
,
getExportDeviceHistoryUrl
,
getDictionaryInfoAll
,
getPointAddress
,
getPointAddressEntry
getPointAddress
,
getPointAddressEntry
,
}
from
'./apis'
;
import
SingleChart
from
'./SingleChart'
;
import
GridChart
from
'./GridChart'
;
import
'./index.less'
;
import
{
globalConfig
}
from
'antd/lib/config-provider'
;
import
{
getSensorType
}
from
"./apis/index"
;
import
{
ExportExcel
}
from
'@wisdom-components/exportexcel'
;
import
{
globalConfig
}
from
'antd/lib/config-provider'
;
import
{
getSensorType
}
from
'./apis/index'
;
import
{
ExportExcel
}
from
'@wisdom-components/exportexcel'
;
const
{
RangePicker
}
=
DatePicker
;
const
{
Option
}
=
Select
;
const
{
RangePicker
}
=
DatePicker
;
const
{
Option
}
=
Select
;
const
startFormat
=
'YYYY-MM-DD 00:00:00'
;
const
endFormat
=
'YYYY-MM-DD 23:59:59'
;
...
...
@@ -57,7 +59,7 @@ const timeList = [
},
{
key
:
'yesterday'
,
name
:
'昨日'
name
:
'昨日'
,
},
{
key
:
'oneWeek'
,
...
...
@@ -73,11 +75,11 @@ const timeList = [
const
shortcutsForDay
=
[
{
label
:
'近3天'
,
value
:
'近3天'
value
:
'近3天'
,
},
{
label
:
'近7天'
,
value
:
'近7天'
value
:
'近7天'
,
},
/* {
label: '去年同期',
...
...
@@ -88,17 +90,17 @@ const shortcutsForDay = [
const
shortcutsForMonth
=
[
{
label
:
'近3月'
,
value
:
'近3月'
value
:
'近3月'
,
},
{
label
:
'近6月'
,
value
:
'近6月'
value
:
'近6月'
,
},
/* {
label: '去年同期',
value: '去年同期',
}*/
]
]
;
const
CheckboxData
=
[
{
...
...
@@ -123,7 +125,7 @@ const CheckboxData = [
showInCurve
:
true
,
showInTable
:
true
,
tooltip
:
'采用递推平均滤波法(滑动平均滤波法)对采样数据中的异常离群值进行识别与去除。'
,
hasSub
:
true
hasSub
:
true
,
},
{
key
:
'dataThin'
,
...
...
@@ -136,6 +138,12 @@ const CheckboxData = [
];
const
timeIntervalList
=
[
{
key
:
'1min'
,
zoom
:
'1'
,
unit
:
'min'
,
name
:
'1分钟'
,
},
{
key
:
'5'
,
zoom
:
'5'
,
...
...
@@ -265,7 +273,7 @@ const OriginMaxDays = 31; // 原始曲线请求数据的最大天数
const
CharacteristicMaxDays
=
null
;
// 特征曲线或者其他曲线的最大天数
const
HistoryView
=
(
props
)
=>
{
const
[
completeInit
,
setCompleteInit
]
=
useState
(
false
);
const
{
getPrefixCls
}
=
useContext
(
ConfigProvider
.
ConfigContext
);
const
{
getPrefixCls
}
=
useContext
(
ConfigProvider
.
ConfigContext
);
const
prefixCls
=
getPrefixCls
(
'history-view'
);
const
{
title
,
...
...
@@ -295,7 +303,9 @@ const HistoryView = (props) => {
const
[
datePickerArr
,
setDatePickerArr
]
=
useState
(
DefaultDatePicker
(
defaultDate
));
// 对比时间段配置值
const
[
checkboxData
,
setCheckboxData
]
=
useState
(()
=>
[...
CheckboxData
]);
// 曲线设置项
const
[
dataThinKey
,
setDataThinKey
]
=
useState
(
timeIntervalList
[
0
].
key
);
// 曲线抽稀时间设置
const
[
dataThinKey
,
setDataThinKey
]
=
useState
(
timeIntervalList
[
0
].
key
===
'1min'
?
timeIntervalList
[
1
].
key
:
timeIntervalList
[
0
].
key
,
);
// 曲线抽稀时间设置
const
[
algorithmValue
,
setAlgorithmValue
]
=
useState
(
1
);
const
[
columns
,
setColumns
]
=
useState
([]);
...
...
@@ -319,11 +329,16 @@ const HistoryView = (props) => {
const
[
isSingleStatusSensor
,
setIsSingleStatusSensor
]
=
useState
(
false
);
// 历史数据相关的特征描述
const
deviceConfig
=
useRef
({
oneDevice
:
deviceParams
.
length
===
1
,
//单设备
oneSensor
:
[...
new
Set
(
deviceParams
.
reduce
((
final
,
cur
)
=>
{
oneDevice
:
deviceParams
.
length
===
1
,
//单设备
oneSensor
:
[
...
new
Set
(
deviceParams
.
reduce
((
final
,
cur
)
=>
{
let
_sensors
=
cur
.
sensors
.
split
(
','
);
return
final
.
concat
(
_sensors
);
},
[]))].
length
===
1
,
// 单指标
},
[]),
),
].
length
===
1
,
// 单指标
});
// 选择的时间范围值
const
dateRange
=
useMemo
(()
=>
{
...
...
@@ -334,7 +349,12 @@ const HistoryView = (props) => {
return
handleBatchTime
(
_dateArr
,
contrastOption
);
}
},
[
contrastOption
,
customerChecked
,
customerTime
,
datePickerArr
,
timeValue
,
shortcutsValue
]);
useEffect
(()
=>
{
let
_diffDays
=
moment
(
dateRange
[
0
].
dateTo
).
diff
(
dateRange
[
0
].
dateFrom
,
'days'
);
if
(
_diffDays
>
7
&&
dataThinKey
===
'1min'
)
{
setDataThinKey
(
timeIntervalList
[
1
].
key
);
}
},
[
dateRange
]);
const
[
dates
,
setDates
]
=
useState
(
null
);
const
configDependence
=
checkboxData
...
...
@@ -400,7 +420,8 @@ const HistoryView = (props) => {
// 同期对比模式: 选择(日/月)
const
onContrastChange
=
(
value
)
=>
{
if
(
value
===
'month'
)
{
if
(
lineDataType
===
'原始曲线'
)
message
.
info
(
'月模式数据量较大,不支持原始曲线模式,已切换为特征曲线'
)
if
(
lineDataType
===
'原始曲线'
)
message
.
info
(
'月模式数据量较大,不支持原始曲线模式,已切换为特征曲线'
);
setLineDataType
(
'特征曲线'
);
}
setShortcutsValue
(
''
);
...
...
@@ -458,13 +479,13 @@ const HistoryView = (props) => {
onContrastChange
(
contrastOption
);
setShowBoxOption
(
false
);
setChartType
(
'lineChart'
);
onCheckboxChange
({
target
:
{
value
:
false
}
},
'chartType'
);
onCheckboxChange
({
target
:
{
value
:
false
}
},
'ignoreOutliers'
);
onCheckboxChange
({
target
:
{
value
:
false
}
},
'chartType'
);
onCheckboxChange
({
target
:
{
value
:
false
}
},
'ignoreOutliers'
);
}
else
{
// 自定义
// 不需要处理
setShowBoxOption
(
true
);
onCheckboxChange
({
target
:
{
value
:
true
}
},
'chartType'
);
onCheckboxChange
({
target
:
{
value
:
true
}
},
'chartType'
);
}
};
const
onShortcutsChange
=
(
e
)
=>
{
...
...
@@ -474,38 +495,38 @@ const HistoryView = (props) => {
switch
(
_val
)
{
case
'近3天'
:
_arr
=
[
{
key
:
1
,
value
:
moment
()
},
{
key
:
2
,
value
:
moment
().
subtract
(
1
,
'days'
)
},
{
key
:
3
,
value
:
moment
().
subtract
(
2
,
'days'
)
},
]
{
key
:
1
,
value
:
moment
()
},
{
key
:
2
,
value
:
moment
().
subtract
(
1
,
'days'
)
},
{
key
:
3
,
value
:
moment
().
subtract
(
2
,
'days'
)
},
];
break
;
case
'近7天'
:
_arr
=
[
{
key
:
1
,
value
:
moment
()
},
{
key
:
2
,
value
:
moment
().
subtract
(
1
,
'days'
)
},
{
key
:
3
,
value
:
moment
().
subtract
(
2
,
'days'
)
},
{
key
:
4
,
value
:
moment
().
subtract
(
3
,
'days'
)
},
{
key
:
5
,
value
:
moment
().
subtract
(
4
,
'days'
)
},
{
key
:
6
,
value
:
moment
().
subtract
(
5
,
'days'
)
},
{
key
:
7
,
value
:
moment
().
subtract
(
6
,
'days'
)
},
]
{
key
:
1
,
value
:
moment
()
},
{
key
:
2
,
value
:
moment
().
subtract
(
1
,
'days'
)
},
{
key
:
3
,
value
:
moment
().
subtract
(
2
,
'days'
)
},
{
key
:
4
,
value
:
moment
().
subtract
(
3
,
'days'
)
},
{
key
:
5
,
value
:
moment
().
subtract
(
4
,
'days'
)
},
{
key
:
6
,
value
:
moment
().
subtract
(
5
,
'days'
)
},
{
key
:
7
,
value
:
moment
().
subtract
(
6
,
'days'
)
},
];
break
;
case
'近3月'
:
_arr
=
[
{
key
:
1
,
value
:
moment
()
},
{
key
:
2
,
value
:
moment
().
subtract
(
1
,
'months'
)
},
{
key
:
3
,
value
:
moment
().
subtract
(
2
,
'months'
)
},
]
{
key
:
1
,
value
:
moment
()
},
{
key
:
2
,
value
:
moment
().
subtract
(
1
,
'months'
)
},
{
key
:
3
,
value
:
moment
().
subtract
(
2
,
'months'
)
},
];
break
;
case
'近6月'
:
_arr
=
[
{
key
:
1
,
value
:
moment
()
},
{
key
:
2
,
value
:
moment
().
subtract
(
1
,
'months'
)
},
{
key
:
3
,
value
:
moment
().
subtract
(
2
,
'months'
)
},
{
key
:
4
,
value
:
moment
().
subtract
(
3
,
'months'
)
},
{
key
:
5
,
value
:
moment
().
subtract
(
4
,
'months'
)
},
{
key
:
6
,
value
:
moment
().
subtract
(
5
,
'months'
)
},
]
{
key
:
1
,
value
:
moment
()
},
{
key
:
2
,
value
:
moment
().
subtract
(
1
,
'months'
)
},
{
key
:
3
,
value
:
moment
().
subtract
(
2
,
'months'
)
},
{
key
:
4
,
value
:
moment
().
subtract
(
3
,
'months'
)
},
{
key
:
5
,
value
:
moment
().
subtract
(
4
,
'months'
)
},
{
key
:
6
,
value
:
moment
().
subtract
(
5
,
'months'
)
},
];
break
;
}
setShortcutsDatePickerArr
(
_arr
);
...
...
@@ -516,9 +537,7 @@ const HistoryView = (props) => {
<
div
className
=
{
classNames
(
`
${
prefixCls
}
-label`
)}
>
时间选择
<
/div
>
<
Radio
.
Group
value
=
{
timeValue
}
onChange
=
{
onTimeSetChange
}
>
<
Radio
.
Button
value
=
"customer"
>
自定义
<
/Radio.Button
>
{
!
grid
?
<
Radio
.
Button
value
=
"contrast"
>
同期对比
<
/Radio.Button> : '
'
}
{
!
grid
?
<
Radio
.
Button
value
=
"contrast"
>
同期对比
<
/Radio.Button> : ''
}
<
/Radio.Group
>
{
timeValue
===
'customer'
&&
(
// 自定义
<>
...
...
@@ -560,30 +579,29 @@ const HistoryView = (props) => {
}}
showTime
=
{{
format
:
'YYYY-MM-DD HH:mm'
,
minuteStep
:
10
minuteStep
:
10
,
}}
/
>
<
/
>
)}
{
timeValue
===
'contrast'
&&
(
// 同期对比
<>
<
Select
value
=
{
contrastOption
}
style
=
{{
width
:
60
}}
onChange
=
{
onContrastChange
}
>
<
Select
value
=
{
contrastOption
}
style
=
{{
width
:
60
}}
onChange
=
{
onContrastChange
}
>
<
Option
value
=
"day"
>
日
<
/Option
>
<
Option
value
=
"month"
disabled
=
{
lineDataType
===
'原始曲线'
}
>
月
<
/Option
>
<
Option
value
=
"month"
disabled
=
{
lineDataType
===
'原始曲线'
}
>
月
<
/Option
>
<
/Select
>
{
/*增加快捷日期*/
}
{
deviceParams
?.
length
===
1
&&
deviceParams
?.[
0
]?.
sensors
?.
split
(
','
).
length
===
1
?
{
deviceParams
?.
length
===
1
&&
deviceParams
?.[
0
]?.
sensors
?.
split
(
','
).
length
===
1
?
(
<
Radio
.
Group
value
=
{
shortcutsValue
}
onChange
=
{
onShortcutsChange
}
>
{
(
contrastOption
===
'day'
?
shortcutsForDay
:
shortcutsForMonth
).
map
(
item
=>
{
return
<
Radio
.
Button
value
=
{
item
.
value
}
>
{
item
.
label
}
<
/Radio.Button
>
})
}
<
/Radio.Group> : '
'
}
{(
contrastOption
===
'day'
?
shortcutsForDay
:
shortcutsForMonth
).
map
((
item
)
=>
{
return
<
Radio
.
Button
value
=
{
item
.
value
}
>
{
item
.
label
}
<
/Radio.Button>
;
})}
<
/Radio.Group
>
)
:
(
''
)}
{
datePickerArr
.
map
((
child
,
index
)
=>
(
<
div
key
=
{
child
.
key
}
className
=
{
classNames
(
`
${
prefixCls
}
-contrast-list`
)}
>
<
div
className
=
{
classNames
(
`
${
prefixCls
}
-contrast-wrap`
)}
>
...
...
@@ -592,14 +610,14 @@ const HistoryView = (props) => {
picker
=
{
contrastOption
===
'day'
?
undefined
:
contrastOption
}
value
=
{
child
.
value
}
onChange
=
{(
date
,
dateString
)
=>
onContrastPickerChange
(
date
,
dateString
,
child
)}
style
=
{{
width
:
130
,
border
:
!
shortcutsValue
?
'1px solid #1890ff'
:
''
}}
style
=
{{
width
:
130
,
border
:
!
shortcutsValue
?
'1px solid #1890ff'
:
''
}}
/
>
{
datePickerArr
.
length
>
2
&&
(
<
div
className
=
{
classNames
(
`
${
prefixCls
}
-contrast-delete`
)}
onClick
=
{()
=>
handleDeleteDatePicker
(
index
)}
>
<
CloseCircleFilled
/>
<
CloseCircleFilled
/>
<
/div
>
)}
<
/div
>
...
...
@@ -608,12 +626,21 @@ const HistoryView = (props) => {
)}
<
/div
>
))}
{
datePickerArr
.
length
<
4
&&
<
PlusCircleOutlined
onClick
=
{
handleAddDatePicker
}
/>
}
{
datePickerArr
.
length
<
4
&&
<
PlusCircleOutlined
onClick
=
{
handleAddDatePicker
}
/>
}
<
/
>
)}
<
/div
>
);
},
[
timeValue
,
customerChecked
,
lineDataType
,
datePickerArr
,
deviceParams
,
dates
,
customerTime
,
chartDataSource
]);
},
[
timeValue
,
customerChecked
,
lineDataType
,
datePickerArr
,
deviceParams
,
dates
,
customerTime
,
chartDataSource
,
]);
// 曲线设置项选择/取消
const
onCheckboxChange
=
(
e
,
key
,
showJustLine
)
=>
{
...
...
@@ -651,7 +678,7 @@ const HistoryView = (props) => {
};
// 切换数据类型
const
switchLineDataType
=
(
e
)
=>
{
let
_val
=
e
.
target
.
value
let
_val
=
e
.
target
.
value
;
let
_startDate
=
dateRange
[
0
]?.
dateFrom
;
let
_endDate
=
dateRange
[
0
]?.
dateTo
;
let
diffDays
=
moment
(
_endDate
).
diff
(
moment
(
_startDate
),
'days'
);
...
...
@@ -662,7 +689,7 @@ const HistoryView = (props) => {
if
(
_val
===
'原始曲线'
)
{
setContrastOption
(
'day'
);
}
setLineDataType
(
_val
)
setLineDataType
(
_val
);
};
const
renderCheckbox
=
(
child
,
showJustLine
)
=>
{
const
curveAccess
=
activeTabKey
===
'curve'
&&
child
.
showInCurve
;
...
...
@@ -678,18 +705,22 @@ const HistoryView = (props) => {
<
/Checkbox
>
{
child
.
tooltip
&&
(
<
Tooltip
title
=
{
child
.
tooltip
}
>
<
QuestionCircleFilled
className
=
{
`
${
prefixCls
}
-question`
}
/
>
<
QuestionCircleFilled
className
=
{
`
${
prefixCls
}
-question`
}
/
>
<
/Tooltip
>
)}
{
child
.
hasSub
&&
child
.
checked
&&
false
?
<
Select
style
=
{{
width
:
80
,
marginLeft
:
10
}}
value
=
{
algorithmValue
}
onChange
=
{(
e
)
=>
setAlgorithmValue
(
e
)}
>
{
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> : '
'
}
<
/Select
>
)
:
(
''
)}
<
/
>
)
);
...
...
@@ -699,51 +730,56 @@ const HistoryView = (props) => {
return
(
<
div
className
=
{
classNames
(
`
${
prefixCls
}
-cover`
)}
style
=
{
isChart
&&
isSingle
?
{
width
:
'100%'
}
:
{}}
style
=
{
isChart
&&
isSingle
?
{
width
:
'100%'
}
:
{}}
>
{
isChart
&&
!
isStatus
?
<>
{
isChart
&&
!
isStatus
?
(
<>
<
div
className
=
{
classNames
(
`
${
prefixCls
}
-label`
)}
>
曲线选择
<
/div
>
<
div
className
=
{
`
${
prefixCls
}
-cover-item`
}
>
<
Radio
.
Group
value
=
{
lineDataType
}
onChange
=
{
switchLineDataType
}
>
<
Radio
.
Group
value
=
{
lineDataType
}
onChange
=
{
switchLineDataType
}
>
<
Radio
.
Button
value
=
{
'特征曲线'
}
>
特征曲线
<
/Radio.Button
>
<
Radio
.
Button
value
=
{
'原始曲线'
}
>
原始曲线
<
/Radio.Button
>
<
/Radio.Group
>
{
/*<Segmented value={lineDataType} options={['特征曲线', '原始曲线']} onChange={switchLineDataType}/>*/
}
<
Tooltip
title
=
{
'原始曲线数据量较大,单次查询最多展示1万条数据'
}
>
<
QuestionCircleFilled
style
=
{{
marginLeft
:
6
}}
className
=
{
`
${
prefixCls
}
-question`
}
/
>
<
QuestionCircleFilled
style
=
{{
marginLeft
:
6
}}
className
=
{
`
${
prefixCls
}
-question`
}
/
>
<
/Tooltip
>
<
/div
>
<
/> : '
'
}
<
/
>
)
:
(
''
)}
{
isChart
&&
isSingle
&&
showBoxOption
&&
!
isStatus
?
(
<>
{
lineDataType
!==
'原始曲线'
?
<>
<
div
style
=
{{
marginLeft
:
7
}}
className
=
{
classNames
(
`
${
prefixCls
}
-label`
)}
>
曲线形态
<
/div
>
{
lineDataType
!==
'原始曲线'
?
(
<>
<
div
style
=
{{
marginLeft
:
7
}}
className
=
{
classNames
(
`
${
prefixCls
}
-label`
)}
>
曲线形态
<
/div
>
<
Radio
.
Group
value
=
{
chartType
}
style
=
{{
marginRight
:
16
}}
style
=
{{
marginRight
:
16
}}
onChange
=
{(
e
)
=>
{
let
_value
=
e
.
target
.
value
;
setChartType
(
_value
);
onCheckboxChange
({
target
:
{
value
:
_value
!==
'boxChart'
}
},
'chartType'
);
onCheckboxChange
({
target
:
{
value
:
_value
!==
'boxChart'
}
},
'chartType'
);
}}
>
<
Radio
.
Button
value
=
{
'lineChart'
}
>
线形图
<
/Radio.Button
>
<
Radio
.
Button
value
=
{
'boxChart'
}
>
箱线图
<
/Radio.Button
>
<
/Radio.Group
>
<
/> : '
'
}
<
/
>
)
:
(
''
)}
{
!
isStatus
?
<
/
>
)
:
(
''
)}
{
!
isStatus
?
(
<>
<
div
className
=
{
classNames
(
`
${
prefixCls
}
-label`
)}
>
{
activeTabKey
!==
'table'
?
'曲线设置'
:
'表格设置'
}
...
...
@@ -760,19 +796,28 @@ const HistoryView = (props) => {
{
activeTabKey
===
'table'
&&
(
<
Select
value
=
{
dataThinKey
}
style
=
{{
width
:
90
}}
style
=
{{
width
:
90
}}
onChange
=
{
onTimeIntervalChange
}
disabled
=
{
!
dataConfig
.
dataThin
}
>
{
timeIntervalList
.
map
((
child
)
=>
(
{
timeIntervalList
.
filter
((
item
)
=>
{
let
_diffDays
=
moment
(
dateRange
[
0
].
dateTo
).
diff
(
dateRange
[
0
].
dateFrom
,
'days'
);
return
!
(
_diffDays
>
7
&&
item
.
key
===
'1min'
);
})
.
map
((
child
)
=>
{
return
(
<
Option
key
=
{
child
.
key
}
unit
=
{
child
.
unit
}
value
=
{
child
.
key
}
>
{
child
.
name
}
<
/Option
>
))}
);
})}
<
/Select
>
)}
<
/> : '
'
}
<
/
>
)
:
(
''
)}
<
/div
>
);
};
...
...
@@ -785,7 +830,10 @@ const HistoryView = (props) => {
let
fileName
=
`数据报表-
${
i
.
deviceType
}
-
${
i
.
deviceCode
}
-
${
moment
(
timeFrom
).
format
(
dateFormat
,
)}
至
${
moment
(
timeTo
).
format
(
dateFormat
)}
`
;
let
_quotas
=
i
.
sensors
.
split
(
','
).
filter
(
item
=>
item
!==
'是否在线'
).
join
(
','
)
let
_quotas
=
i
.
sensors
.
split
(
','
)
.
filter
((
item
)
=>
item
!==
'是否在线'
)
.
join
(
','
);
getExportDeviceHistoryUrl
({
deviceType
:
i
.
deviceType
,
deviceCode
:
i
.
deviceCode
,
...
...
@@ -802,15 +850,14 @@ const HistoryView = (props) => {
aDom.click();
aDom.remove();
})
.catch((err) => {
});
.catch((err) => {});
});
};
const exportFeatureBtn = () => {
message.info('报表生成中,请稍后~');
let _dataSource = tableData.sort((a, b) => {
let _a = a.time;
let _b = b.time
let _b = b.time;
if (timeValue === 'contrast') {
if (contrastOption === 'day') {
_a = `
2000
-
01
-
01
$
{
a
.
time
}:
00
`;
...
...
@@ -822,37 +869,40 @@ const HistoryView = (props) => {
}
}
return
timeOrder
===
'ascend'
?
moment
(
_a
)
-
moment
(
_b
)
:
moment
(
_b
)
-
moment
(
_a
);
})
});
let
_columns
=
[...
columns
];
let
timeFrom
=
dateRange
?.[
0
]?.
dateFrom
||
moment
().
format
(
startFormat
);
let
timeTo
=
dateRange
?.[
0
]?.
dateTo
||
moment
().
format
(
timeFormat
);
let
fileName
=
`特征数据-
${
moment
(
timeFrom
).
format
(
let
fileName
=
`特征数据-
${
moment
(
timeFrom
).
format
(
dateFormat
)}
至
${
moment
(
timeTo
).
format
(
dateFormat
,
)}
至
${
moment
(
timeTo
).
format
(
dateFormat
)}
`
;
)}
`
;
let
_dataIndex
=
[];
let
_titleWidth
=
[];
let
_title
=
_columns
.
map
(
item
=>
{
let
_title
=
_columns
.
map
((
item
)
=>
{
_dataIndex
.
push
(
item
.
dataIndex
);
let
_titleStr
=
[
item
.
name
,
item
.
title
].
filter
(
item
=>
item
).
join
(
'-'
);
let
_titleStr
=
[
item
.
name
,
item
.
title
].
filter
((
item
)
=>
item
).
join
(
'-'
);
_titleWidth
.
push
(
_titleStr
.
length
*
1
);
return
_titleStr
;
});
ExportExcel
({
name
:
fileName
,
content
:
[{
content
:
[
{
sheetData
:
_dataSource
,
sheetFilter
:
_dataIndex
,
sheetHeader
:
_title
,
columnWidths
:
_titleWidth
}]
})
columnWidths
:
_titleWidth
,
},
],
});
};
const
handleTableData
=
useCallback
((
data
)
=>
{
const
handleTableData
=
useCallback
(
(
data
)
=>
{
// eslint-disable-next-line no-param-reassign
// data = data.filter(item => item.sensorName !== '是否在线');
const
ignoreOutliers
=
checkboxData
.
find
((
item
)
=>
item
.
key
===
'ignoreOutliers'
).
checked
;
const
dataIndexAccess
=
(
dataItem
,
index
)
=>
{
const
{
stationCode
,
sensorName
}
=
dataItem
;
const
{
stationCode
,
sensorName
}
=
dataItem
;
return
`
${
stationCode
}
-
${
sensorName
}
-
${
index
}
`
;
};
...
...
@@ -863,13 +913,13 @@ const HistoryView = (props) => {
// 判断是否是单设备,单设备则不显示设备名称
// 处理表头数据
const
columnsData
=
data
.
map
((
item
,
index
)
=>
{
const
{
stationCode
,
equipmentName
,
sensorName
,
unit
,
dataModel
}
=
item
;
const
{
stationCode
,
equipmentName
,
sensorName
,
unit
,
dataModel
}
=
item
;
const
dataIndex
=
dataIndexAccess
(
item
,
index
);
let
_title
=
''
;
if
(
deviceConfig
.
current
.
oneDevice
)
{
_title
=
`
${
sensorName
}${
unit
?
`(
${
unit
}
)`
:
''
}
`
;
}
else
{
_title
=
`
${
equipmentName
}
-
${
sensorName
}${
unit
?
`(
${
unit
}
)`
:
''
}
`
_title
=
`
${
equipmentName
}
-
${
sensorName
}${
unit
?
`(
${
unit
}
)`
:
''
}
`
;
}
let
col
=
{
title
:
_title
,
...
...
@@ -878,7 +928,7 @@ const HistoryView = (props) => {
ellipsis
:
true
,
align
:
'center'
,
width
:
200
,
name
:
equipmentName
name
:
equipmentName
,
};
// 同期对比
if
(
timeValue
===
'contrast'
&&
dataModel
[
0
])
{
...
...
@@ -893,7 +943,7 @@ const HistoryView = (props) => {
// 格式化时间对齐数据, 生成行数
const
timeData
=
{};
const
buildDefaultData
=
(
time
)
=>
{
const
obj
=
{
key
:
time
,
time
:
time
};
const
obj
=
{
key
:
time
,
time
:
time
};
data
.
forEach
((
item
,
index
)
=>
{
const
dataIndex
=
dataIndexAccess
(
item
,
index
);
obj
[
dataIndex
]
=
''
;
...
...
@@ -902,7 +952,7 @@ const HistoryView = (props) => {
return
obj
;
};
data
.
forEach
((
item
,
index
)
=>
{
const
{
stationCode
,
sensorName
,
dataModel
}
=
item
;
const
{
stationCode
,
sensorName
,
dataModel
}
=
item
;
dataModel
&&
dataModel
.
forEach
((
data
)
=>
{
const
formatTime
=
moment
(
data
.
pt
).
format
(
format
);
...
...
@@ -917,7 +967,7 @@ const HistoryView = (props) => {
});
// 处理表格数据
data
.
forEach
((
child
,
index
)
=>
{
const
{
dataModel
}
=
child
;
const
{
dataModel
}
=
child
;
const
dataIndex
=
dataIndexAccess
(
child
,
index
);
dataModel
&&
dataModel
.
forEach
((
value
,
j
)
=>
{
...
...
@@ -941,7 +991,9 @@ const HistoryView = (props) => {
const
tableData
=
times
.
map
((
time
)
=>
timeData
[
time
]);
setColumns
([
timeColumn
,
...
columnsData
]);
setTableData
(
tableData
);
},
[
timeOrder
,
timeValue
,
contrastOption
]);
},
[
timeOrder
,
timeValue
,
contrastOption
],
);
const
[
deviceAlarmSchemes
,
setDeviceAlarmSchemes
]
=
useState
([]);
const
beforChangeParams
=
(
value
=
{})
=>
{
...
...
@@ -966,40 +1018,45 @@ const HistoryView = (props) => {
};
const
handleDataThinKey
=
(
diffYears
,
diffDays
,
diffHours
,
lineDataType
)
=>
{
if
(
lineDataType
===
'原始曲线'
)
{
return
{
unit
:
''
,
zoom
:
''
}
return
{
unit
:
''
,
zoom
:
''
};
}
// edit by zy 根据选择的时长控制抽稀频度
if
(
diffYears
>
0
)
{
if
(
diffYears
===
1
)
return
{
unit
:
'h'
,
zoom
:
'24'
}
return
{
unit
:
'h'
,
zoom
:
'48'
}
if
(
diffYears
===
1
)
return
{
unit
:
'h'
,
zoom
:
'24'
};
return
{
unit
:
'h'
,
zoom
:
'48'
};
}
else
if
(
diffYears
===
0
&&
diffDays
>
0
)
{
if
(
diffDays
>
90
)
return
{
unit
:
'h'
,
zoom
:
'24'
}
if
(
diffDays
>
30
)
return
{
unit
:
'h'
,
zoom
:
'4'
}
if
(
diffDays
>
15
)
return
{
unit
:
'h'
,
zoom
:
'2'
}
if
(
diffDays
>
7
)
return
{
unit
:
'h'
,
zoom
:
'1'
}
if
(
diffDays
>
3
)
return
{
unit
:
'min'
,
zoom
:
'20'
}
if
(
diffDays
>
1
)
return
{
unit
:
'min'
,
zoom
:
'15'
}
if
(
diffDays
===
1
)
return
{
unit
:
'min'
,
zoom
:
'5'
}
if
(
diffDays
>
90
)
return
{
unit
:
'h'
,
zoom
:
'24'
};
if
(
diffDays
>
30
)
return
{
unit
:
'h'
,
zoom
:
'4'
};
if
(
diffDays
>
15
)
return
{
unit
:
'h'
,
zoom
:
'2'
};
if
(
diffDays
>
7
)
return
{
unit
:
'h'
,
zoom
:
'1'
};
if
(
diffDays
>
3
)
return
{
unit
:
'min'
,
zoom
:
'20'
};
if
(
diffDays
>
1
)
return
{
unit
:
'min'
,
zoom
:
'15'
};
if
(
diffDays
===
1
)
return
{
unit
:
'min'
,
zoom
:
'5'
};
}
else
if
(
diffYears
===
0
&&
diffDays
===
0
&&
diffHours
>
0
)
{
if
(
diffHours
>
12
)
return
{
unit
:
'min'
,
zoom
:
'5'
}
if
(
diffHours
>
4
)
return
{
unit
:
'min'
,
zoom
:
'1'
}
if
(
diffHours
>
1
)
return
{
unit
:
's'
,
zoom
:
'30'
}
if
(
diffHours
>
0
)
return
{
unit
:
's'
,
zoom
:
'5'
}
return
{
unit
:
's'
,
zoom
:
'5'
}
if
(
diffHours
>
12
)
return
{
unit
:
'min'
,
zoom
:
'5'
};
if
(
diffHours
>
4
)
return
{
unit
:
'min'
,
zoom
:
'1'
};
if
(
diffHours
>
1
)
return
{
unit
:
's'
,
zoom
:
'30'
};
if
(
diffHours
>
0
)
return
{
unit
:
's'
,
zoom
:
'5'
};
return
{
unit
:
's'
,
zoom
:
'5'
};
}
else
{
return
{
unit
:
''
,
zoom
:
''
}
return
{
unit
:
''
,
zoom
:
''
};
}
};
// 处理接口服务参数的变化
const
onChangeParams
=
(
value
=
{})
=>
{
const
{
dateRange
,
isDilute
,
ignoreOutliers
,
zoom
,
unit
}
=
value
;
const
{
dateRange
,
isDilute
,
ignoreOutliers
,
zoom
,
unit
}
=
value
;
let
_diffDays
=
moment
(
dateRange
[
0
].
dateTo
).
diff
(
dateRange
[
0
].
dateFrom
,
'days'
);
// 查询时段大于7天时,不提供1分钟的抽稀选项。
if
(
_diffDays
>
7
&&
zoom
===
'1'
&&
unit
===
'min'
)
{
return
false
;
}
const
requestArr
=
[];
const
acrossTables
=
[];
const
zoomArray
=
[];
deviceParams
.
map
((
item
)
=>
{
let
_item
=
{...
item
};
let
_item
=
{
...
item
};
// 历史曲线中,是否在线暂时去除,不显示 要显示是否在线解开这里即可 2023-09-15
/* _item.sensors =
item.sensors && !item.sensors.includes('是否在线')
...
...
@@ -1037,17 +1094,21 @@ const HistoryView = (props) => {
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'
);
let
zoomParam
=
activeTabKey
===
'curve'
?
handleDataThinKey
(
diffYears
,
diffDays
,
diffHours
,
lineDataType
)
:
{};
zoomArray
.
push
(
zoomParam
);
requestArr
.
push
(
getHistoryInfo
({...
param
,
...
zoomParam
}));
let
zoomParam
=
activeTabKey
===
'curve'
?
handleDataThinKey
(
diffYears
,
diffDays
,
diffHours
,
lineDataType
)
:
{};
requestArr
.
push
(
getHistoryInfo
({
...
param
,
...
zoomParam
}));
});
setLoading
(
true
);
Promise
.
all
(
requestArr
).
then
((
results
)
=>
{
Promise
.
all
(
requestArr
)
.
then
((
results
)
=>
{
setLoading
(
false
);
if
(
results
.
length
)
{
let
data
=
[];
results
.
forEach
((
res
,
index
)
=>
{
const
{
dateFrom
,
dateTo
}
=
dateRange
?.[
index
]
??
{};
const
{
dateFrom
,
dateTo
}
=
dateRange
?.[
index
]
??
{};
if
(
res
.
code
===
0
&&
res
.
data
.
length
)
{
res
.
data
.
forEach
((
d
)
=>
{
d
.
dateFrom
=
dateFrom
||
''
;
...
...
@@ -1062,7 +1123,8 @@ const HistoryView = (props) => {
sensors
.
push
(
special1
.
name
);
}
}
const
list
=
sensors
.
map
((
s
)
=>
{
const
list
=
sensors
.
map
((
s
)
=>
{
const
dataItem
=
res
.
data
.
find
(
(
d
)
=>
d
.
stationCode
===
p
.
deviceCode
&&
d
.
sensorName
===
s
,
);
...
...
@@ -1073,7 +1135,8 @@ const HistoryView = (props) => {
}
else
{
return
{};
}
}).
filter
(
item
=>
item
.
sensorName
);
})
.
filter
((
item
)
=>
item
.
sensorName
);
data
=
data
.
concat
(
list
);
});
}
...
...
@@ -1082,15 +1145,16 @@ const HistoryView = (props) => {
handleTableData
(
data
);
setChartDataSource
(
data
);
}
}).
catch
(
err
=>
{
})
.
catch
((
err
)
=>
{
message
.
info
(
'未查询到数据,请重试~'
);
setLoading
(
false
)
setLoading
(
false
);
});
};
useEffect
(()
=>
{
if
(
!
completeInit
)
return
;
const
{
dataThin
,
ignoreOutliers
,
zoom
,
unit
}
=
dataConfig
;
const
{
dataThin
,
ignoreOutliers
,
zoom
,
unit
}
=
dataConfig
;
beforChangeParams
().
finally
(()
=>
{
onChangeParams
({
isDilute
:
dataThin
,
...
...
@@ -1104,11 +1168,12 @@ const HistoryView = (props) => {
},
[
dateRange
,
dataConfig
,
deviceParams
,
chartType
,
lineDataType
,
completeInit
,
algorithmValue
]);
const
handleChange
=
(
pagination
,
filter
,
sort
)
=>
{
if
(
sort
.
field
===
'time'
)
{
setTimeOrder
(
sort
.
order
)
setTimeOrder
(
sort
.
order
);
}
};
const
tableMemo
=
useMemo
(()
=>
{
return
<>
return
(
<>
<
div
className
=
{
`
${
prefixCls
}
-options`
}
>
{
renderTimeOption
}
{
renderCurveOption
()}
...
...
@@ -1118,7 +1183,7 @@ const HistoryView = (props) => {
<
BasicTable
dataSource
=
{
tableData
.
sort
((
a
,
b
)
=>
{
let
_a
=
a
.
time
;
let
_b
=
b
.
time
let
_b
=
b
.
time
;
if
(
timeValue
===
'contrast'
)
{
if
(
contrastOption
===
'day'
)
{
_a
=
`2000-01-01
${
a
.
time
}
:00`
;
...
...
@@ -1135,32 +1200,33 @@ const HistoryView = (props) => {
{...
tableProps
}
pagination
=
{
false
}
onChange
=
{
handleChange
}
scroll
=
{{
x
:
'max-content'
,
y
:
'calc(100% - 40px)'
}}
scroll
=
{{
x
:
'max-content'
,
y
:
'calc(100% - 40px)'
}}
/
>
)
:
(
<
PandaEmpty
/>
<
PandaEmpty
/>
)}
<
/div
>
<
/
>
},
[
timeOrder
,
chartDataSource
,
columns
,
tableProps
,
tableData
,
isSingleStatusSensor
])
);
},
[
timeOrder
,
chartDataSource
,
columns
,
tableProps
,
tableData
,
isSingleStatusSensor
,
dateRange
]);
const
returnLongestPeriod
=
(
data
)
=>
{
let
_earliest
=
''
let
_earliest
=
''
;
let
_latest
=
''
;
data
.
forEach
(
item
=>
{
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
_earliest
=
moment
(
_earliest
)
>
moment
(
_tempFirst
)
?
_tempFirst
:
_earliest
;
}
else
{
_earliest
=
_tempFirst
_earliest
=
_tempFirst
;
}
if
(
_latest
)
{
_latest
=
moment
(
_latest
)
<
moment
(
_tempLast
)
?
_tempLast
:
_latest
_latest
=
moment
(
_latest
)
<
moment
(
_tempLast
)
?
_tempLast
:
_latest
;
}
else
{
_latest
=
_tempLast
;
}
})
});
return
`
${
_earliest
}
-
${
_latest
}
`
;
};
const
renderPanel
=
(
model
)
=>
{
...
...
@@ -1172,16 +1238,17 @@ const HistoryView = (props) => {
{
renderCurveOption
(
true
,
deviceParams
?.
length
===
1
&&
deviceParams
?.[
0
]?.
sensors
?.
split
(
','
).
length
===
1
,
isSingleStatusSensor
isSingleStatusSensor
,
)}
<
/div
>
{
lineDataType
===
'原始曲线'
&&
false
?
<
div
style
=
{{
marginTop
:
10
}}
>
展示区间:
{
returnLongestPeriod
(
chartDataSource
)}
<
/div> : '
'
}
{
lineDataType
===
'原始曲线'
&&
false
?
(
<
div
style
=
{{
marginTop
:
10
}}
>
展示区间:
{
returnLongestPeriod
(
chartDataSource
)}
<
/div
>
)
:
(
''
)}
<
div
className
=
{
`
${
prefixCls
}
-content`
}
>
{
!
chartDataSource
.
length
?
(
<
PandaEmpty
/>
<
PandaEmpty
/>
)
:
grid
===
true
?
(
<
GridChart
curveCenter
=
{
curveCenter
}
...
...
@@ -1221,24 +1288,28 @@ const HistoryView = (props) => {
// 获取字段配置
const
getDefaultOptions
=
async
()
=>
{
// 非单曲线、单指标不执行
if
(
deviceParams
?.
length
!==
1
||
(
deviceParams
?.
length
===
1
&&
deviceParams
?.[
0
]?.
sensors
?.
split
(
','
)?.
length
>
1
))
return
setCompleteInit
(
true
);
if
(
deviceParams
?.
length
!==
1
||
(
deviceParams
?.
length
===
1
&&
deviceParams
?.[
0
]?.
sensors
?.
split
(
','
)?.
length
>
1
)
)
return
setCompleteInit
(
true
);
setLoading
(
true
);
const
{
deviceCode
,
deviceType
,
sensors
}
=
deviceParams
[
0
];
let
_id
=
(
await
getPointAddress
({
code
:
deviceCode
}))?.
data
?.[
0
]?.
id
;
let
_params
=
{
// deviceType: deviceType
};
const
{
deviceCode
,
deviceType
,
sensors
}
=
deviceParams
[
0
];
let
_id
=
(
await
getPointAddress
({
code
:
deviceCode
,
})
)?.
data
?.[
0
]?.
id
;
let
_params
=
{
};
if
(
_id
)
_params
.
versionId
=
_id
;
// 多曲线的居中,容易导致曲线被截断,故多曲线时,不请求
let
_request0
=
getDictionaryInfoAll
({
level
:
'组件_ec_historyview'
level
:
'组件_ec_historyview'
,
});
// 以下请求为处理状态值、开关值的图表,只允许单曲线单指标情况下展示
let
_request1
=
getPointAddressEntry
(
_params
);
let
_request2
=
getSensorType
();
await
Promise
.
all
([
_request0
,
_request1
,
_request2
]).
then
(
result
=>
{
await
Promise
.
all
([
_request0
,
_request1
,
_request2
]).
then
((
result
)
=>
{
if
(
result
)
{
let
_res0
=
result
[
0
];
let
_res1
=
result
[
1
];
...
...
@@ -1246,13 +1317,13 @@ const HistoryView = (props) => {
// 查字典配置
if
(
_res0
.
code
===
0
)
{
let
_opt
=
_res0
.
data
.
reduce
((
final
,
cur
)
=>
{
final
[
cur
.
fieldName
]
=
cur
.
fieldValue
return
final
final
[
cur
.
fieldName
]
=
cur
.
fieldValue
;
return
final
;
},
{});
let
_checkboxData
=
[...
checkboxData
].
map
(
item
=>
{
let
_item
=
{...
item
};
let
_checkboxData
=
[...
checkboxData
].
map
((
item
)
=>
{
let
_item
=
{
...
item
};
if
(
_opt
[
item
.
label
]
!==
undefined
)
{
_item
.
checked
=
_opt
[
item
.
label
]
===
'true'
_item
.
checked
=
_opt
[
item
.
label
]
===
'true'
;
}
return
_item
;
});
...
...
@@ -1260,19 +1331,19 @@ const HistoryView = (props) => {
}
// 查点表配置
if
(
_res1
.
code
===
0
)
{
let
_sensorConfig
=
_res1
.
data
.
find
(
item
=>
item
?.
name
.
trim
()
===
sensors
.
trim
());
let
_sensorConfig
=
_res1
.
data
.
find
((
item
)
=>
item
?.
name
.
trim
()
===
sensors
.
trim
());
let
_statusName
=
_sensorConfig
?.
statusName
;
setAllPointAddress
(
_res1
.
data
);
if
(
_statusName
)
{
let
_statusConfig
=
_res1
.
data
.
find
(
item
=>
item
?.
name
.
trim
()
===
_statusName
.
trim
());
let
_statusConfig
=
_res1
.
data
.
find
((
item
)
=>
item
?.
name
.
trim
()
===
_statusName
.
trim
());
let
_valDesc
=
_statusConfig
?.
valDesc
||
''
;
setSpecial1
({
name
:
_statusName
,
valDesc
:
_valDesc
.
split
(
';'
).
reduce
((
final
,
cur
)
=>
{
let
_arr
=
cur
.
split
(
':'
);
final
[
_arr
[
0
]]
=
_arr
[
1
];
return
final
},
{})
return
final
;
},
{}),
});
}
}
...
...
@@ -1280,8 +1351,8 @@ const HistoryView = (props) => {
if
(
_res2
.
code
===
0
)
{
setAllSensorType
(
_res2
.
data
);
let
_sensorID
=
_res1
.
data
?.
find
(
item
=>
item
.
name
===
sensors
)?.
sensorTypeID
;
let
_sensor
=
_res2
.
data
?.
find
(
item
=>
item
.
id
===
_sensorID
)?.
type
;
let
_sensorID
=
_res1
.
data
?.
find
((
item
)
=>
item
.
name
===
sensors
)?.
sensorTypeID
;
let
_sensor
=
_res2
.
data
?.
find
((
item
)
=>
item
.
id
===
_sensorID
)?.
type
;
let
_isStatusSensor
=
[
'状态值'
,
'开关值'
].
includes
(
_sensor
);
setIsSingleStatusSensor
(
_isStatusSensor
);
}
...
...
@@ -1291,10 +1362,11 @@ const HistoryView = (props) => {
};
useEffect
(()
=>
{
getDefaultOptions
();
},
[
deviceParams
])
},
[
deviceParams
]);
let
percentTimer
=
useRef
({
timer
:
null
timer
:
null
,
});
// 加载动画
useEffect
(()
=>
{
if
(
loading
===
null
)
return
;
if
(
loading
)
{
...
...
@@ -1303,34 +1375,45 @@ const HistoryView = (props) => {
_percent
+=
5
;
if
(
_percent
>
95
)
return
clearInterval
(
percentTimer
.
current
.
timer
);
setPercent
(
_percent
);
},
100
)
},
100
);
}
else
{
clearInterval
(
percentTimer
.
current
.
timer
);
setPercent
(
100
);
setTimeout
(()
=>
{
setTimeout
(
()
=>
{
setPercent
(
0
);
},
lineDataType
===
'原始曲线'
?
500
:
0
)
},
lineDataType
===
'原始曲线'
?
500
:
0
,
);
}
},
[
loading
])
},
[
loading
]);
return
(
<
div
className
=
{
classNames
(
prefixCls
,
'wkt-scroll-light'
)}
>
<
div
className
=
{
classNames
(
`
${
prefixCls
}
-spin`
)}
style
=
{{
position
:
"relative"
}}
>
{
(
loading
||
percent
!==
0
)
?
<
div
className
=
{
classNames
(
`
${
prefixCls
}
-progressWrapper`
)}
>
<
div
className
=
{
classNames
(
`
${
prefixCls
}
-spin`
)}
style
=
{{
position
:
'relative'
}}
>
{
loading
||
percent
!==
0
?
(
<
div
className
=
{
classNames
(
`
${
prefixCls
}
-progressWrapper`
)}
>
<
div
className
=
{
classNames
(
`
${
prefixCls
}
-contentWrapper`
)}
>
{
lineDataType
===
'原始曲线'
||
lineDataType
===
'特征曲线'
&&
moment
(
dateRange
?.[
0
]?.
dateTo
).
diff
(
moment
(
dateRange
?.[
0
]?.
dateFrom
),
'days'
)
>=
30
?
<>
<
Progress
percent
=
{
percent
}
{
lineDataType
===
'原始曲线'
||
(
lineDataType
===
'特征曲线'
&&
moment
(
dateRange
?.[
0
]?.
dateTo
).
diff
(
moment
(
dateRange
?.[
0
]?.
dateFrom
),
'days'
)
>=
30
)
?
(
<>
<
Progress
percent
=
{
percent
}
steps
=
{
20
}
className
=
{
classNames
(
`
${
prefixCls
}
-progress`
,
`
${
prefixCls
}
-blink-2`
)}
showInfo
=
{
false
}
/
>
showInfo
=
{
false
}
/
>
<
div
className
=
{
classNames
(
`
${
prefixCls
}
-tip`
)}
>
加载中
...
<
/div
>
<
/> : <Spin spinning={loading || false}/
>
}
<
/
>
)
:
(
<
Spin
spinning
=
{
loading
||
false
}
/
>
)}
<
/div
>
<
/div> : '
'
}
<
/div
>
)
:
(
''
)}
{
showModels
.
length
===
1
&&
(
<
div
className
=
{
`
${
prefixCls
}
-single-panel`
}
>
{
renderPanel
(
showModels
[
0
])}
<
/div
>
)}
...
...
@@ -1346,11 +1429,11 @@ const HistoryView = (props) => {
{
activeTabKey
===
'table'
&&
(
<>
<
Button
type
=
"link"
onClick
=
{
exportFeatureBtn
}
>
<
DownloadOutlined
/>
<
DownloadOutlined
/>
特征数据
<
/Button
>
<
Button
type
=
"link"
onClick
=
{
exportExcelBtn
}
>
<
DownloadOutlined
/>
<
DownloadOutlined
/>
原始数据
<
/Button
>
<
/
>
...
...
@@ -1360,9 +1443,7 @@ const HistoryView = (props) => {
}}
>
<
Tabs
.
TabPane
key
=
"curve"
tab
=
"曲线"
forceRender
=
{
true
}
>
{
activeTabKey
===
'curve'
?
renderPanel
(
'curve'
)
:
''
}
{
activeTabKey
===
'curve'
?
renderPanel
(
'curve'
)
:
''
}
<
/Tabs.TabPane
>
<
Tabs
.
TabPane
key
=
"table"
tab
=
"表格"
>
{
renderPanel
(
'table'
)}
...
...
packages/extend-components/EC_HistoryView/src/utils.js
View file @
365230d8
import
moment
from
'moment'
;
import
_
,
{
isArray
}
from
'lodash'
;
import
_
,
{
isArray
}
from
'lodash'
;
import
maxIcon
from
'./assets/最大实心.svg'
;
import
minIcon
from
'./assets/最小实心.svg'
;
import
minIconDownArrow
from
'./assets/最小实心箭头朝下.svg'
;
import
lineChart
from
'@wisdom-components/basicchart/es/LineChart'
;
import
*
as
echarts
from
"echarts"
;
import
*
as
echarts
from
'echarts'
;
/** 轴宽度, 用于计算多轴显示时, 轴线偏移和绘图区域尺寸 */
const
AXIS_WIDTH
=
40
;
...
...
@@ -68,7 +68,7 @@ const currentOption = isMobile() ? MOBILE_OPTION : PC_OPTION;
* @returns
*/
const
nameFormatter
=
(
data
,
contrast
,
contrastOption
,
nameWithSensor
)
=>
{
const
{
equipmentName
,
sensorName
,
unit
,
dataModel
,
dateFrom
,
dateTo
}
=
data
;
const
{
equipmentName
,
sensorName
,
unit
,
dataModel
,
dateFrom
,
dateTo
}
=
data
;
let
name
=
nameWithSensor
?
`
${
equipmentName
}
-
${
sensorName
}
`
:
equipmentName
;
if
(
contrast
)
{
const
time
=
dateFrom
.
slice
(
0
,
contrastOption
===
'day'
?
10
:
7
).
replace
(
/-/g
,
''
);
...
...
@@ -103,7 +103,7 @@ const dataAccessor = (data, contrast, contrastOption) => {
* @returns Null/areaStyle, 为null显示曲线图, 为areaStyle对象显示为面积图.
*/
const
areaStyleFormatter
=
(
data
)
=>
{
const
{
sensorName
}
=
data
;
const
{
sensorName
}
=
data
;
return
sensorName
&&
sensorName
.
indexOf
(
'流量'
)
>
-
1
?
{}
:
null
;
};
...
...
@@ -114,7 +114,7 @@ const areaStyleFormatter = (data) => {
* @returns
*/
const
minMax
=
(
data
)
=>
{
const
{
dataModel
}
=
data
;
const
{
dataModel
}
=
data
;
let
min
=
Number
.
MAX_SAFE_INTEGER
;
let
max
=
Number
.
MIN_SAFE_INTEGER
;
dataModel
.
forEach
((
item
)
=>
{
...
...
@@ -145,7 +145,7 @@ const markLineItem = (name, value, color) => {
export
const
alarmMarkLine
=
(
dataItem
,
index
,
dataSource
,
schemes
)
=>
{
// 只有一个数据曲线时显示markline
if
(
!
dataItem
||
!
schemes
||
dataSource
.
length
!==
1
)
return
{};
const
{
deviceType
,
stationCode
,
sensorName
,
decimalPoint
}
=
dataItem
;
const
{
deviceType
,
stationCode
,
sensorName
,
decimalPoint
}
=
dataItem
;
const
curSchemes
=
schemes
.
filter
(
(
item
)
=>
item
.
deviceCode
===
stationCode
&&
...
...
@@ -154,7 +154,7 @@ export const alarmMarkLine = (dataItem, index, dataSource, schemes) => {
);
const
data
=
[];
curSchemes
.
forEach
((
scheme
)
=>
{
const
{
hLimit
,
hhLimit
,
lLimit
,
llLimit
}
=
scheme
;
const
{
hLimit
,
hhLimit
,
lLimit
,
llLimit
}
=
scheme
;
lLimit
!==
null
&&
lLimit
!==
void
0
&&
data
.
push
(
markLineItem
(
'低限'
,
lLimit
,
'#fa8c16'
));
hLimit
!==
null
&&
hLimit
!==
void
0
&&
data
.
push
(
markLineItem
(
'高限'
,
hLimit
,
'#fa8c16'
));
llLimit
!==
null
&&
llLimit
!==
void
0
&&
data
.
push
(
markLineItem
(
'低低限'
,
llLimit
,
'#FF0000'
));
...
...
@@ -246,7 +246,7 @@ export const decorateAxisGridLine = (axis, showGrid) => {
*/
export
const
offlineArea
=
(
dataItem
)
=>
{
if
(
!
dataItem
)
return
{};
const
{
dataModel
}
=
dataItem
;
const
{
dataModel
}
=
dataItem
;
let
datas
=
new
Array
();
let
offlineData
=
[];
let
hasOffline
=
false
;
...
...
@@ -256,7 +256,7 @@ export const offlineArea = (dataItem) => {
{
name
:
'离线'
,
xAxis
:
new
Date
(
item
.
pt
),
label
:
{
show
:
!
datas
?.
length
},
label
:
{
show
:
!
datas
?.
length
},
},
];
hasOffline
=
true
;
...
...
@@ -280,7 +280,7 @@ export const offlineArea = (dataItem) => {
// tooltip 模板
const
headTemplate
=
(
param
,
opt
)
=>
{
if
(
!
param
)
return
''
;
const
{
name
,
axisValueLabel
,
axisType
,
axisValue
}
=
param
;
const
{
name
,
axisValueLabel
,
axisType
,
axisValue
}
=
param
;
const
timeFormat
=
opt
&&
opt
.
contrast
?
opt
.
contrastOption
===
'day'
...
...
@@ -296,57 +296,65 @@ const headTemplate = (param, opt) => {
};
const
seriesTemplate
=
(
param
,
unit
)
=>
{
if
(
!
param
||
param
.
seriesName
===
'自定义'
)
return
''
;
const
{
value
,
encode
}
=
param
;
const
{
value
,
encode
}
=
param
;
// const val = value[encode.y[0]];
const
_unit
=
unit
||
''
;
const
color
=
'#008CFF'
;
if
(
!
isArray
(
value
))
return
` <div style="display: flex; align-items: center;">
<span style="
${
isMobile
()
<span style="
${
isMobile
()
?
'width: '
+
handlePx
(
90
,
'px'
)
+
';overflow:hidden;text-overflow:ellipsis;white-space:nowrap'
:
''
}
">
${
param
.
seriesName
}
</span>
<span style="display:inline-block;">:</span>
<span style="color:
${
color
}
;margin: 0
${
handlePx
(
5
,
'px'
)}
0 auto;">
${
value
?.
toFixed
(
3
)
??
'-'
<span style="color:
${
color
}
;margin: 0
${
handlePx
(
5
,
'px'
)}
0 auto;">
${
value
?.
toFixed
(
3
)
??
'-'
}
<
/span
>
<
span
style
=
"font-size: ${handlePx(12, 'px')};"
>
$
{
_unit
??
''
}
<
/span
>
<
/div>`
;
return
param
.
componentSubType
!==
'candlestick'
?
`<div style="display: flex; align-items: center;">
<span style="
${
isMobile
()
<span style="
${
isMobile
()
?
'width: '
+
handlePx
(
90
,
'px'
)
+
';overflow:hidden;text-overflow:ellipsis;white-space:nowrap'
:
''
}
">
${
param
.
seriesName
}
</span><span style="display:inline-block;">:</span>
<span style="color:
${
COLOR
.
AVG
}
;margin: 0
${
handlePx
(
5
,
'px'
)}
0 auto;">
${
value
[
1
]
??
'-'
<span style="color:
${
COLOR
.
AVG
}
;margin: 0
${
handlePx
(
5
,
'px'
)}
0 auto;">
${
value
[
1
]
??
'-'
}
<
/span
>
<
span
style
=
"font-size: ${handlePx(12, 'px')};"
>
$
{
_unit
??
''
}
<
/span
>
<
/div>
`
:
`
<div style="display: flex; align-items: center;">
<span>首值</span><span style="display:inline-block;">:</span>
<span style="color:
${
COLOR
.
AVG
}
;margin: 0
${
handlePx
(
5
,
'px'
)}
0 auto;">
${
value
[
1
]
??
'-'
<span style="color:
${
COLOR
.
AVG
}
;margin: 0
${
handlePx
(
5
,
'px'
)}
0 auto;">
${
value
[
1
]
??
'-'
}
<
/span
>
<
span
style
=
"font-size: ${handlePx(12, 'px')};"
>
$
{
_unit
??
''
}
<
/span
>
<
/div
>
<
div
style
=
"display: flex; align-items: center;"
>
<
span
>
尾值
<
/span><span style="display:inline-block;">:</
span
>
<
span
style
=
"color: ${COLOR.AVG};margin: 0 ${handlePx(5, 'px')} 0 auto;"
>
$
{
value
[
2
]
??
'-'
<
span
style
=
"color: ${COLOR.AVG};margin: 0 ${handlePx(5, 'px')} 0 auto;"
>
$
{
value
[
2
]
??
'-'
}
<
/span
>
<
span
style
=
"font-size: ${handlePx(12, 'px')};"
>
$
{
_unit
??
''
}
<
/span
>
<
/div
>
<
div
style
=
"display: flex; align-items: center;"
>
<
span
>
周期最小值
<
/span><span style="display:inline-block;">:</
span
>
<
span
style
=
"color: ${COLOR.AVG};margin: 0 ${handlePx(5, 'px')} 0 auto;"
>
$
{
value
[
3
]
??
'-'
<
span
style
=
"color: ${COLOR.AVG};margin: 0 ${handlePx(5, 'px')} 0 auto;"
>
$
{
value
[
3
]
??
'-'
}
<
/span
>
<
span
style
=
"font-size: ${handlePx(12, 'px')};"
>
$
{
_unit
??
''
}
<
/span
>
<
/div
>
<
div
style
=
"display: flex; align-items: center;"
>
<
span
>
周期最大值
<
/span><span style="display:inline-block;">:</
span
>
<
span
style
=
"color: ${COLOR.AVG};margin: 0 ${handlePx(5, 'px')} 0 auto;"
>
$
{
value
[
4
]
??
'-'
<
span
style
=
"color: ${COLOR.AVG};margin: 0 ${handlePx(5, 'px')} 0 auto;"
>
$
{
value
[
4
]
??
'-'
}
<
/span
>
<
span
style
=
"font-size: ${handlePx(12, 'px')};"
>
$
{
_unit
??
''
}
<
/span
>
<
/div
>
...
...
@@ -409,7 +417,7 @@ const handleSpecial1 = (special, dataSource) => {
} else {
final.push({
lte: _pt,
gte: _pt
,
gte: final[_length - 1].gte
,
color: _colorMap[_valDesc[cur.pv]],
value: cur.pv,
text: _valDesc[cur.pv],
...
...
@@ -445,7 +453,7 @@ const handleSpecial1 = (special, dataSource) => {
},
},
name: item.text,
label: {show: true
},
label: { show: true
},
},
{
xAxis: item.lte,
...
...
@@ -490,18 +498,18 @@ const returnXAxis = ({
restOption,
smooth,
special,
yAxis
}) => {
yAxis,
}) => {
// 根据"指标名称"分类yAxis
const yAxisInterator = (() => {
const map = new Map();
let current = -1;
const get = (name) => (map.has(name) ? map.get(name) : map.set(name, ++current).get(name));
return {get
};
return { get
};
})();
let _offlineData = [];
// 生成visualMap、markArea
let {visualMap, markArea
} = handleSpecial1(special, dataSource);
let { visualMap, markArea
} = handleSpecial1(special, dataSource);
let _filterArr = ['是否在线'];
if (special?.special1?.name) {
_filterArr.push(special.special1.name);
...
...
@@ -515,12 +523,12 @@ const returnXAxis = ({
return !_filterArr.includes(item.sensorName);
})
.map((item, index) => {
const {sensorName, unit
} = item;
const { sensorName, unit
} = item;
const name = nameFormatter(item, contrast, contrastOption, nameWithSensor);
const data = dataAccessor(item, contrast, contrastOption);
const type = 'line';
const areaStyle = areaStyleFormatter(item);
const _index = yAxis.findIndex(item
=> item.name === unit);
const _index = yAxis.findIndex((item)
=> item.name === unit);
const yAxisIndex = _index > -1 ? _index : 0;
const markLine = showMarkLine
? alarmMarkLine(item, index, dataSource, deviceAlarmSchemes)
...
...
@@ -616,70 +624,69 @@ const handleMaxValue = (value) => {
if (value <= 1) return value.toFixed(2);
if (value >= 100000) return `
$
{(
value
/
1000
).
toFixed
(
2
)}
k
`;
return value.toFixed(2);
}
}
;
const reduceYAxis = (arr, dataSource) => {
let _offsetValue = [];
// 1. 合并相同单位的坐标轴
let _arr = arr.reduce((final, cur) => {
let _key = cur.name === null ? 'null' : cur.name
let _key = cur.name === null ? 'null' : cur.name;
if (!final[_key]) {
final[_key] = cur
final[_key] = cur;
}
return final;
}, {});
// 2. 合并相同单位的数据,找出最大值
let _maxValueArr = Object.values(dataSource.reduce((final, cur) => {
let _maxValueArr = Object.values(
dataSource.reduce((final, cur) => {
let _key = cur.sensorName === null ? 'null' : cur.sensorName;
let _maxValue = cur.dataModel.reduce((final, cur) => {
// eslint-disable-next-line no-param-reassign
if (cur.pv > final) final = cur.pv;
return final
return final;
}, 0);
if (final[_key] === undefined) {
final[_key] = _maxValue
final[_key] = _maxValue;
} else {
final[_key] = Math.max([final[_key], _maxValue]);
}
return final
}, {}));
return final;
}, {}),
);
// 3. 合并,生成Y轴配置
return Object.values(_arr).map((item, index) => {
let _key = item.name === null ? 'null' : item.name;
let _lastAxisNumber = _maxValueArr[index - 2];
let _baseOffset = _offsetValue[index - 2] ?? 0;
let _finalOffset = (
_lastAxisNumber !== undefined ? // 没有相邻的轴
(_lastAxisNumber === 0 ? 20 : _lastAxisNumber.toFixed(2).replaceAll('.', '').length) * 12
: 0
) + _baseOffset;
let _finalOffset =
(_lastAxisNumber !== undefined // 没有相邻的轴
? (_lastAxisNumber === 0 ? 20 : _lastAxisNumber.toFixed(2).replaceAll('.', '').length) * 12
: 0) + _baseOffset;
_offsetValue.push(_finalOffset);
return (
{
return
{
...item,
offset: _finalOffset,
position: index % 2 === 0 ? 'left' : 'right',
nameTextStyle: {
align: index % 2 === 0 ? 'right' : 'left',
},
})
};
});
};
/**
*
* 1. 生成常规的yAxis配置;
* 2. 处理sensorType为状态值的指标,生成yAxis配置
* 1. 生成常规的yAxis配置; 2. 处理sensorType为状态值的指标,生成yAxis配置
*
* @param {array} dataSource 数据源
* @param {boolean} needUnit 是否显示单位。
* @param {boolean} curveCenter 曲线是否居中。
* @param {boolean} showGridLine 是否显示网格线。
*
@return
{object} 返回左右轴的margin、yAxis的配置。
*
*
/
const handleYAxis = ({
dataSource, needUnit, curveCenter, showGridLine
}) => {
*
@returns
{object} 返回左右轴的margin、yAxis的配置。
*/
const handleYAxis = ({
dataSource, needUnit, curveCenter, showGridLine
}) => {
const yAxisMap = new Map();
// 1. 找出最大值; 2. 计算出y轴最大宽度动态计算偏移距离;
dataSource.forEach((item, index) => {
const {sensorName, unit
} = item;
const { sensorName, unit
} = item;
const key = sensorName;
if (!yAxisMap.has(key)) {
const axis = {
...
...
@@ -688,7 +695,7 @@ const handleYAxis = ({dataSource, needUnit, curveCenter, showGridLine}) => {
axisLabel: {
formatter: (value) => {
return handleMaxValue(value);
}
},
},
axisLine: {
show: true,
...
...
@@ -718,25 +725,35 @@ const handleYAxis = ({dataSource, needUnit, curveCenter, showGridLine}) => {
const axis = yAxisMap.get(key);
decorateAxisGridLine(axis, showGridLine);
});
const yAxis = yAxisMap.size > 0 ? reduceYAxis([...yAxisMap.values()], dataSource) : {type: 'value'};
const yAxis =
yAxisMap.size > 0 ? reduceYAxis([...yAxisMap.values()], dataSource) : { type: 'value' };
const leftNum = Math.ceil(yAxisMap.size / 2);
const rightNum = Math.floor(yAxisMap.size / 2);
return {leftNum, rightNum, yAxis
};
return { leftNum, rightNum, yAxis
};
};
/**
* 1. 最后的配置处理、合并
* dataZoom 缩放
* xAxis.minInterval X轴的最小间隔
* legend legend配置
*
* @param {object} restOption 额外配置
*
@param {object} xAxis x
轴的配置
*
@param {array} legendData l
egend数组
*
@param {object} xAxis X
轴的配置
*
@param {array} legendData L
egend数组
* @param {string} chartType 线型 lineChart|boxChart
* @param {boolean} contrast 是否为同期对比
* @param {string} contrastOption 同期对比周期配置, day|month
* @param {object} config 其他的配置
* */
const assignOptions = (restOption, xAxis, legendData, chartType, contrast, contrastOption, config) => {
*/
const assignOptions = (
restOption,
xAxis,
legendData,
chartType,
contrast,
contrastOption,
config,
) => {
restOption.dataZoom = [
{
show: true,
...
...
@@ -771,13 +788,15 @@ const assignOptions = (restOption, xAxis, legendData, chartType, contrast, contr
restOption.legend = {
...{
show: true,
right:
10,
right:
10,
top: 30,
icon: 'rect',
itemWidth: 14,
itemHeight: 8,
itemGap: 20,
}, ...restOption.legend, ...{data: legendData}
},
...restOption.legend,
...{ data: legendData },
};
}
};
...
...
@@ -912,24 +931,24 @@ const renderStatusItem = (params, api) => {
x: start[0],
y: start[1] - height / 2,
width: end[0] - start[0],
height: height
height: height,
},
{
x: params.coordSys.x,
y: params.coordSys.y,
width: params.coordSys.width,
height: params.coordSys.height
}
height: params.coordSys.height,
},
);
return (
rectShape && {
type: 'rect',
transition: ['shape'],
shape: rectShape,
style: api.style()
style: api.style(),
}
);
}
}
;
/**
* 图表配置项生成
...
...
@@ -965,13 +984,13 @@ const optionGenerator = (
restOption,
special,
} = handleDefault(config, cusOption);
const {leftNum, rightNum, yAxis
} = handleYAxis({
const { leftNum, rightNum, yAxis
} = handleYAxis({
dataSource,
needUnit,
curveCenter,
showGridLine,
});
let {xAxis, series, visualMap
} = returnXAxis({
let { xAxis, series, visualMap
} = returnXAxis({
dataSource,
contrast,
contrastOption,
...
...
@@ -982,7 +1001,7 @@ const optionGenerator = (
smooth,
restOption,
special,
yAxis
yAxis,
});
// 3. 判断是否开启网格;
const grid = handleGrid(dataSource, needUnit, leftNum, rightNum, chartType);
...
...
@@ -998,19 +1017,20 @@ const optionGenerator = (
if (chartType === 'boxChart' && lineDataType === '特征曲线') {
const otherData =
dataSource?.[0]?.dataModel.map((item) => {
const {firstPV, lastPV, maxPV, minPV, pt
} = item;
const { firstPV, lastPV, maxPV, minPV, pt
} = item;
return [moment(pt).valueOf(), firstPV, lastPV, minPV, maxPV];
}) || []; //当存在othersData的时候,只是单曲线
xAxis = {type: 'time'
};
xAxis = { type: 'time'
};
decorateAxisGridLine(xAxis, showGridLine);
let unit = [];
series = series.map((item) => {
if (item.unit) unit.push(item.unit);
item.areaStyle = null;
return {...item, showSymbol: false
};
return { ...item, showSymbol: false
};
});
// 箱线图去除曲线 2023年10月17日
series=[{
series = [
{
type: 'candlestick',
name: '箱线图',
symbol: 'none',
...
...
@@ -1021,7 +1041,8 @@ const optionGenerator = (
borderColor: '#FFA200',
borderColor0: '#44CD00',
},
}];
},
];
tooltip = tooltipAccessor(unit);
}
if (chartType === 'lineChart' || lineDataType === '原始曲线') {
...
...
@@ -1033,13 +1054,9 @@ const optionGenerator = (
? `
$
{
_currentYear
}
-
01
-
01
HH
:
mm
:
00
`
: `
$
{
_currentYear
}
-
01
-
DD
HH
:
mm
:
00
`; // 用来做同期对比,把日期拉到同一区间
let _maxValues = [];
/**
* 生成泳道图,分两种情况
* 1. 当最大值最小值都是正数时;
* 2. 当最大值小于零时(此时,最小值一定小于零);
*/
/** 生成泳道图,分两种情况 1. 当最大值最小值都是正数时; 2. 当最大值小于零时(此时,最小值一定小于零); */
dataSource?.[0]?.dataModel.forEach((item) => {
const {firstPV, lastPV, maxPV, minPV, pt
} = item;
const { firstPV, lastPV, maxPV, minPV, pt
} = item;
_maxValues.push(maxPV);
let time = contrast ? moment(pt).format(formatStr) : pt;
_maxData.push([
...
...
@@ -1049,13 +1066,13 @@ const optionGenerator = (
_minData.push([moment(time).valueOf(), maxPV > 0 ? minPV : maxPV]);
}); //当存在othersData的时候,只是单曲线
// xAxis = {type: 'category', data: series[0].data.map(item => moment(item[0]).format('YYYY-MM-DD HH:mm:ss'))};
xAxis = {type: 'time'
};
xAxis = { type: 'time'
};
decorateAxisGridLine(xAxis, showGridLine);
let _unit = '';
series = series.map((item) => {
_unit = item.unit ?? '';
item.areaStyle = null;
return {...item, showSymbol: false
};
return { ...item, showSymbol: false
};
});
[[..._minData], [..._maxData]].forEach((item, index) => {
series.push({
...
...
@@ -1084,12 +1101,14 @@ const optionGenerator = (
$
{
headTemplate
(
e
[
0
])}
<
div
>
<
div
style
=
"display: flex; align-items: center;"
>
<
span
style
=
"${isMobile()
<
span
style
=
"${
isMobile()
? 'width: ' +
handlePx(90, 'px') +
';overflow:hidden;text-overflow:ellipsis;white-space:nowrap'
: ''
}"
>
$
{
e
[
0
].
seriesName
}"
>
$
{
e
[
0
].
seriesName
}
<
/span><span style="display:inline-block;">:</
span
>
<
span
style
=
"color: ${COLOR.NORMAL};margin: 0 ${handlePx(
5,
...
...
@@ -1097,7 +1116,8 @@ const optionGenerator = (
)} 0 auto;"
>
$
{
e
[
0
]?.
value
?.[
1
]
??
'-'
}
<
/span
>
<
span
style
=
"font-size: ${handlePx(12, 'px')};"
>
$
{
_unit
??
''
}
<
/span
>
<
/div
>
<
div
style
=
"display: ${lineDataType === '特征曲线' ? 'flex' : 'none'
<
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(
...
...
@@ -1106,7 +1126,8 @@ const optionGenerator = (
)} 0 auto;"
>
$
{
e
?.[
1
]?.
value
?.[
1
]
??
'-'
}
<
/span
>
<
span
style
=
"font-size: ${handlePx(12, 'px')};"
>
$
{
_unit
??
''
}
<
/span
>
<
/div
>
<
div
style
=
"display: ${lineDataType === '特征曲线' ? 'flex' : 'none'
<
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(
...
...
@@ -1128,7 +1149,7 @@ const optionGenerator = (
}
else
{
tooltip
=
tooltipAccessor
(
series
.
map
((
item
)
=>
item
.
unit
),
{
contrastOption
,
contrast
},
{
contrastOption
,
contrast
},
);
}
tooltip
.
timeFormat
=
tooltipTimeFormat
;
...
...
@@ -1157,7 +1178,7 @@ const handleDataSource = (dataSource) => {
// handleSpecial2()
dataSource
[
0
].
dataModel
.
forEach
((
item
,
index
)
=>
{
if
(
index
===
0
)
{
_data
.
push
(
item
)
_data
.
push
(
item
);
}
else
if
(
index
===
_dataLength
-
1
)
{
_data
.
push
(
item
);
}
else
{
...
...
@@ -1167,7 +1188,7 @@ const handleDataSource = (dataSource) => {
}
_temp
=
item
;
});
return
_data
return
_data
;
};
const
returnLegend
=
(
sensorType
)
=>
{
const
_colorMap
=
{
...
...
@@ -1195,7 +1216,7 @@ const handleSpecial2 = (special, sensorName, sensorType, data1, data2) => {
let
_valDescMap
=
special
.
allValDesc
[
sensorName
]?.
split
(
';'
).
reduce
((
final
,
cur
)
=>
{
let
_arr
=
cur
.
split
(
':'
);
final
[
_arr
[
0
]]
=
_arr
[
1
];
return
final
return
final
;
},
{});
name
=
_valDescMap
[
data1
.
pv
];
color
=
_colorMap
[
name
];
...
...
@@ -1205,48 +1226,64 @@ const handleSpecial2 = (special, sensorName, sensorType, data1, data2) => {
if
(
sensorType
===
'开关值'
)
{
const
_switchColorMap
=
{
0
:
'#666666'
,
1
:
'#1685ff'
1
:
'#1685ff'
,
};
const
_switchNameMap
=
{
0
:
'关'
,
1
:
'开'
}
1
:
'开'
,
};
name
=
_switchNameMap
[
data1
.
pv
];
color
=
_switchColorMap
[
data1
.
pv
];
}
value1
=
moment
(
data1
.
pt
).
valueOf
();
value2
=
moment
(
data2
.
pt
).
valueOf
();
return
{
color
,
value1
,
value2
,
name
}
return
{
color
,
value1
,
value2
,
name
};
};
const
handleDataToSeries
=
(
special
,
sensorName
,
sensorType
,
data
)
=>
{
let
_data
=
[];
let
_legend
=
[];
data
.
forEach
((
item
,
index
)
=>
{
if
(
index
===
data
.
length
-
1
)
return
;
let
{
color
,
value1
,
value2
,
name
}
=
handleSpecial2
(
special
,
sensorName
,
sensorType
,
item
,
data
[
index
+
1
])
let
{
color
,
value1
,
value2
,
name
}
=
handleSpecial2
(
special
,
sensorName
,
sensorType
,
item
,
data
[
index
+
1
],
);
if
(
!
_legend
.
includes
(
name
))
_legend
.
push
(
name
);
_data
.
push
({
itemStyle
:
{
normal
:
{
color
}
},
itemStyle
:
{
normal
:
{
color
}
},
name
:
name
,
value
:
[
0
,
value1
,
value2
,
`
${
item
.
pt
}
-
${
data
[
index
+
1
].
pt
}
`
]
value
:
[
0
,
value1
,
value2
,
`
${
item
.
pt
}
-
${
data
[
index
+
1
].
pt
}
`
],
});
});
return
{
data
:
_data
,
legend
:
_legend
};
return
{
data
:
_data
,
legend
:
_legend
};
};
const
specialTypeChartOptionGenerator
=
({
dataSource
,
cusOption
,
contrast
,
contrastOption
,
smooth
,
config
})
=>
{
const
{
special
,
sensorType
}
=
config
;
const
{
allSensorType
,
allPointAddress
}
=
special
;
const
specialTypeChartOptionGenerator
=
({
dataSource
,
cusOption
,
contrast
,
contrastOption
,
smooth
,
config
,
})
=>
{
const
{
special
,
sensorType
}
=
config
;
const
{
allSensorType
,
allPointAddress
}
=
special
;
// 处理原始数据,处理数据为后series数据
const
sensorName
=
dataSource
[
0
].
sensorName
;
let
_data
=
handleDataSource
(
dataSource
);
let
{
data
,
legend
}
=
handleDataToSeries
(
special
,
sensorName
,
sensorType
,
_data
);
let
{
data
,
legend
}
=
handleDataToSeries
(
special
,
sensorName
,
sensorType
,
_data
);
// 1. x/y轴
let
xAxis
=
{
type
:
'time'
,
axisLabel
:
{
formatter
:
contrast
?
(
contrastOption
===
'month'
?
'{dd}日'
:
'{HH}:{mm}'
)
formatter
:
contrast
?
contrastOption
===
'month'
?
'{dd}日'
:
'{HH}:{mm}'
:
{
year
:
'{yyyy}'
,
month
:
'{MMM}'
,
...
...
@@ -1259,44 +1296,44 @@ const specialTypeChartOptionGenerator = ({dataSource, cusOption, contrast, contr
},
minorTick
:
{
lineStyle
:
{
color
:
"#e2e2e2"
color
:
'#e2e2e2'
,
},
show
:
true
,
splitNumber
:
2
splitNumber
:
2
,
},
minorSplitLine
:
{
lineStyle
:
{
color
:
"#e2e2e2"
,
type
:
"dashed"
color
:
'#e2e2e2'
,
type
:
'dashed'
,
},
show
:
true
show
:
true
,
},
splitLine
:
{
show
:
true
show
:
true
,
},
minInterval
:
3600
*
1000
minInterval
:
3600
*
1000
,
};
let
yAxis
=
{
data
:
[
dataSource
[
0
].
sensorName
],
axisLine
:
{
show
:
true
show
:
true
,
},
minorTick
:
{
lineStyle
:
{
color
:
"#e2e2e2"
color
:
'#e2e2e2'
,
},
show
:
true
,
splitNumber
:
2
splitNumber
:
2
,
},
minorSplitLine
:
{
lineStyle
:
{
color
:
"#e2e2e2"
,
type
:
"dashed"
color
:
'#e2e2e2'
,
type
:
'dashed'
,
},
show
:
true
show
:
true
,
},
splitLine
:
{
show
:
true
show
:
true
,
},
};
//2. series
...
...
@@ -1305,15 +1342,15 @@ const specialTypeChartOptionGenerator = ({dataSource, cusOption, contrast, contr
type
:
'custom'
,
renderItem
:
renderStatusItem
,
itemStyle
:
{
opacity
:
0.8
opacity
:
0.8
,
},
encode
:
{
x
:
[
1
,
2
],
y
:
0
y
:
0
,
},
data
data
,
},
...
legend
.
map
(
item
=>
{
...
legend
.
map
((
item
)
=>
{
let
_map
=
{
变频
:
'#1685ff'
,
工频
:
'#00d0c7'
,
...
...
@@ -1321,23 +1358,22 @@ const specialTypeChartOptionGenerator = ({dataSource, cusOption, contrast, contr
故障
:
'#ff6b37'
,
停止
:
'#666666'
,
关
:
'#666666'
,
开
:
'#1685ff'
}
开
:
'#1685ff'
,
};
return
{
type
:
'custom'
,
name
:
item
,
color
:
_map
[
item
],
renderItem
:
()
=>
{
}
}
})
renderItem
:
()
=>
{},
};
}),
];
let
grid
=
{
top
:
80
,
left
:
30
,
right
:
10
,
bottom
:
60
,
containLabel
:
true
containLabel
:
true
,
};
let
legendConfig
=
{
show
:
true
,
...
...
@@ -1360,23 +1396,21 @@ const specialTypeChartOptionGenerator = ({dataSource, cusOption, contrast, contr
trigger
:
'item'
,
formatter
:
function
(
params
)
{
return
params
.
marker
+
params
.
name
+
': '
+
params
?.
value
?.[
3
];
}
},
},
dataZoom
:
[
{
type
:
'slider'
,
filterMode
:
'weakFilter'
,
showDataShadow
:
false
,
labelFormatter
:
''
labelFormatter
:
''
,
},
{
type
:
'inside'
,
filterMode
:
'weakFilter'
}
filterMode
:
'weakFilter'
,
},
],
}
};
return
_option
;
};
export
{
specialTypeChartOptionGenerator
}
\ No newline at end of file
export
{
specialTypeChartOptionGenerator
};
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment