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
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
1202 additions
and
1169 deletions
+1202
-1169
index.js
packages/extend-components/EC_HistoryView/src/index.js
+0
-0
utils.js
packages/extend-components/EC_HistoryView/src/utils.js
+1202
-1169
No files found.
packages/extend-components/EC_HistoryView/src/index.js
View file @
365230d8
This source diff could not be displayed because it is too large. You can
view the blob
instead.
packages/extend-components/EC_HistoryView/src/utils.js
View file @
365230d8
import
moment
from
'moment'
;
import
moment
from
'moment'
;
import
_
,
{
isArray
}
from
'lodash'
;
import
_
,
{
isArray
}
from
'lodash'
;
import
maxIcon
from
'./assets/最大实心.svg'
;
import
maxIcon
from
'./assets/最大实心.svg'
;
import
minIcon
from
'./assets/最小实心.svg'
;
import
minIcon
from
'./assets/最小实心.svg'
;
import
minIconDownArrow
from
'./assets/最小实心箭头朝下.svg'
;
import
minIconDownArrow
from
'./assets/最小实心箭头朝下.svg'
;
import
lineChart
from
'@wisdom-components/basicchart/es/LineChart'
;
import
lineChart
from
'@wisdom-components/basicchart/es/LineChart'
;
import
*
as
echarts
from
"echarts"
;
import
*
as
echarts
from
'echarts'
;
/** 轴宽度, 用于计算多轴显示时, 轴线偏移和绘图区域尺寸 */
/** 轴宽度, 用于计算多轴显示时, 轴线偏移和绘图区域尺寸 */
const
AXIS_WIDTH
=
40
;
const
AXIS_WIDTH
=
40
;
const
COLOR
=
{
const
COLOR
=
{
NORMAL
:
'#1685FF'
,
NORMAL
:
'#1685FF'
,
UPER
:
'#fa8c16'
,
UPER
:
'#fa8c16'
,
UPUPER
:
'#FF0000'
,
UPUPER
:
'#FF0000'
,
// LOWER: '#13c2c2',
// LOWER: '#13c2c2',
// LOWLOWER: '#2f54eb',
// LOWLOWER: '#2f54eb',
LOWER
:
'#fa8c16'
,
LOWER
:
'#fa8c16'
,
LOWLOWER
:
'#FF0000'
,
LOWLOWER
:
'#FF0000'
,
AVG
:
'#00B8B1'
,
AVG
:
'#00B8B1'
,
};
};
const
isMobile
=
()
=>
{
const
isMobile
=
()
=>
{
const
userAgent
=
navigator
.
userAgent
.
toLowerCase
();
const
userAgent
=
navigator
.
userAgent
.
toLowerCase
();
if
(
/ipad|iphone|midp|rv:1.2.3.4|ucweb|android|windows ce|windows mobile/
.
test
(
userAgent
))
{
if
(
/ipad|iphone|midp|rv:1.2.3.4|ucweb|android|windows ce|windows mobile/
.
test
(
userAgent
))
{
return
true
;
return
true
;
}
}
return
false
;
return
false
;
};
};
const
returnRem
=
(
num
,
base
=
375
)
=>
num
*
(
base
/
375
);
const
returnRem
=
(
num
,
base
=
375
)
=>
num
*
(
base
/
375
);
export
const
handlePx
=
(
num
,
unit
=
''
)
=>
{
export
const
handlePx
=
(
num
,
unit
=
''
)
=>
{
const
_isMobile
=
isMobile
();
const
_isMobile
=
isMobile
();
const
_base
=
document
.
body
.
clientWidth
;
const
_base
=
document
.
body
.
clientWidth
;
let
_num
=
_isMobile
?
`
${
returnRem
(
num
,
_base
)}
`
:
`
${
num
}
`
;
let
_num
=
_isMobile
?
`
${
returnRem
(
num
,
_base
)}
`
:
`
${
num
}
`
;
return
unit
?
`
${
_num
}${
unit
}
`
:
Number
(
_num
);
return
unit
?
`
${
_num
}${
unit
}
`
:
Number
(
_num
);
};
};
const
PC_OPTION
=
{
const
PC_OPTION
=
{
markPoint
:
{
markPoint
:
{
padding
:
[
2
,
12
],
padding
:
[
2
,
12
],
lineHeight
:
22
,
lineHeight
:
22
,
backgroundColor
:
backgroundColor
:
window
.
globalConfig
&&
window
.
globalConfig
&&
window
.
globalConfig
.
variableTheme
?.
primaryColor
window
.
globalConfig
&&
window
.
globalConfig
&&
window
.
globalConfig
.
variableTheme
?.
primaryColor
?
window
.
globalConfig
.
variableTheme
.
primaryColor
?
window
.
globalConfig
.
variableTheme
.
primaryColor
:
'#0087F7'
,
:
'#0087F7'
,
borderWidth
:
1
,
borderWidth
:
1
,
},
},
fontSize
:
16
,
fontSize
:
16
,
fontColor
:
'#ffffff'
,
fontColor
:
'#ffffff'
,
dataZoomHeight
:
28
,
dataZoomHeight
:
28
,
};
};
const
MOBILE_OPTION
=
{
const
MOBILE_OPTION
=
{
markPoint
:
{
markPoint
:
{
padding
:
[
2
,
6
],
padding
:
[
2
,
6
],
lineHeight
:
18
,
lineHeight
:
18
,
backgroundColor
:
'rgba(255,255,255,0.6)'
,
backgroundColor
:
'rgba(255,255,255,0.6)'
,
borderWidth
:
0
,
borderWidth
:
0
,
},
},
fontSize
:
handlePx
(
12
),
fontSize
:
handlePx
(
12
),
fontColor
:
'#0087F7'
,
fontColor
:
'#0087F7'
,
dataZoomHeight
:
20
,
dataZoomHeight
:
20
,
};
};
const
currentOption
=
isMobile
()
?
MOBILE_OPTION
:
PC_OPTION
;
const
currentOption
=
isMobile
()
?
MOBILE_OPTION
:
PC_OPTION
;
/**
/**
...
@@ -68,13 +68,13 @@ const currentOption = isMobile() ? MOBILE_OPTION : PC_OPTION;
...
@@ -68,13 +68,13 @@ const currentOption = isMobile() ? MOBILE_OPTION : PC_OPTION;
* @returns
* @returns
*/
*/
const
nameFormatter
=
(
data
,
contrast
,
contrastOption
,
nameWithSensor
)
=>
{
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
;
let
name
=
nameWithSensor
?
`
${
equipmentName
}
-
${
sensorName
}
`
:
equipmentName
;
if
(
contrast
)
{
if
(
contrast
)
{
const
time
=
dateFrom
.
slice
(
0
,
contrastOption
===
'day'
?
10
:
7
).
replace
(
/-/g
,
''
);
const
time
=
dateFrom
.
slice
(
0
,
contrastOption
===
'day'
?
10
:
7
).
replace
(
/-/g
,
''
);
name
=
`
${
name
}
-
${
time
}
`
;
name
=
`
${
name
}
-
${
time
}
`
;
}
}
return
name
;
return
name
;
};
};
/**
/**
...
@@ -86,14 +86,14 @@ const nameFormatter = (data, contrast, contrastOption, nameWithSensor) => {
...
@@ -86,14 +86,14 @@ const nameFormatter = (data, contrast, contrastOption, nameWithSensor) => {
* @returns 图表系列数据, [[DateTime, value]]
* @returns 图表系列数据, [[DateTime, value]]
*/
*/
const
dataAccessor
=
(
data
,
contrast
,
contrastOption
)
=>
{
const
dataAccessor
=
(
data
,
contrast
,
contrastOption
)
=>
{
const
dataModel
=
data
?.
dataModel
??
[];
const
dataModel
=
data
?.
dataModel
??
[];
const
formatStr
=
contrastOption
===
'day'
?
'2020-01-01 HH:mm:ss'
:
'2020-01-DD HH:mm:ss'
;
const
formatStr
=
contrastOption
===
'day'
?
'2020-01-01 HH:mm:ss'
:
'2020-01-DD HH:mm:ss'
;
return
dataModel
return
dataModel
.
filter
((
item
)
=>
item
.
sensorName
!==
'是否在线'
)
.
filter
((
item
)
=>
item
.
sensorName
!==
'是否在线'
)
.
map
((
item
)
=>
{
.
map
((
item
)
=>
{
const
time
=
contrast
?
moment
(
item
.
pt
).
format
(
formatStr
)
:
item
.
pt
;
const
time
=
contrast
?
moment
(
item
.
pt
).
format
(
formatStr
)
:
item
.
pt
;
return
[
moment
(
time
).
valueOf
(),
item
.
pv
];
return
[
moment
(
time
).
valueOf
(),
item
.
pv
];
});
});
};
};
/**
/**
...
@@ -103,8 +103,8 @@ const dataAccessor = (data, contrast, contrastOption) => {
...
@@ -103,8 +103,8 @@ const dataAccessor = (data, contrast, contrastOption) => {
* @returns Null/areaStyle, 为null显示曲线图, 为areaStyle对象显示为面积图.
* @returns Null/areaStyle, 为null显示曲线图, 为areaStyle对象显示为面积图.
*/
*/
const
areaStyleFormatter
=
(
data
)
=>
{
const
areaStyleFormatter
=
(
data
)
=>
{
const
{
sensorName
}
=
data
;
const
{
sensorName
}
=
data
;
return
sensorName
&&
sensorName
.
indexOf
(
'流量'
)
>
-
1
?
{}
:
null
;
return
sensorName
&&
sensorName
.
indexOf
(
'流量'
)
>
-
1
?
{}
:
null
;
};
};
/**
/**
...
@@ -114,100 +114,100 @@ const areaStyleFormatter = (data) => {
...
@@ -114,100 +114,100 @@ const areaStyleFormatter = (data) => {
* @returns
* @returns
*/
*/
const
minMax
=
(
data
)
=>
{
const
minMax
=
(
data
)
=>
{
const
{
dataModel
}
=
data
;
const
{
dataModel
}
=
data
;
let
min
=
Number
.
MAX_SAFE_INTEGER
;
let
min
=
Number
.
MAX_SAFE_INTEGER
;
let
max
=
Number
.
MIN_SAFE_INTEGER
;
let
max
=
Number
.
MIN_SAFE_INTEGER
;
dataModel
.
forEach
((
item
)
=>
{
dataModel
.
forEach
((
item
)
=>
{
min
=
Math
.
min
(
min
,
item
.
pv
??
0
);
min
=
Math
.
min
(
min
,
item
.
pv
??
0
);
max
=
Math
.
max
(
max
,
item
.
pv
??
0
);
max
=
Math
.
max
(
max
,
item
.
pv
??
0
);
});
});
return
[
min
,
max
];
return
[
min
,
max
];
};
};
const
markLineItem
=
(
name
,
value
,
color
)
=>
{
const
markLineItem
=
(
name
,
value
,
color
)
=>
{
return
{
return
{
name
:
name
,
name
:
name
,
yAxis
:
value
,
yAxis
:
value
,
value
:
value
,
value
:
value
,
lineStyle
:
{
lineStyle
:
{
color
:
color
||
'#000'
,
color
:
color
||
'#000'
,
},
},
label
:
{
label
:
{
position
:
'insideEndTop'
,
position
:
'insideEndTop'
,
color
:
color
||
'#000'
,
color
:
color
||
'#000'
,
formatter
:
function
()
{
formatter
:
function
()
{
return
`
${
name
}
:
${
value
}
`
;
return
`
${
name
}
:
${
value
}
`
;
},
},
},
},
};
};
};
};
export
const
alarmMarkLine
=
(
dataItem
,
index
,
dataSource
,
schemes
)
=>
{
export
const
alarmMarkLine
=
(
dataItem
,
index
,
dataSource
,
schemes
)
=>
{
// 只有一个数据曲线时显示markline
// 只有一个数据曲线时显示markline
if
(
!
dataItem
||
!
schemes
||
dataSource
.
length
!==
1
)
return
{};
if
(
!
dataItem
||
!
schemes
||
dataSource
.
length
!==
1
)
return
{};
const
{
deviceType
,
stationCode
,
sensorName
,
decimalPoint
}
=
dataItem
;
const
{
deviceType
,
stationCode
,
sensorName
,
decimalPoint
}
=
dataItem
;
const
curSchemes
=
schemes
.
filter
(
const
curSchemes
=
schemes
.
filter
(
(
item
)
=>
(
item
)
=>
item
.
deviceCode
===
stationCode
&&
item
.
deviceCode
===
stationCode
&&
item
.
sensorName
===
sensorName
&&
item
.
sensorName
===
sensorName
&&
item
.
valueType
===
'直接取值'
,
item
.
valueType
===
'直接取值'
,
);
);
const
data
=
[];
const
data
=
[];
curSchemes
.
forEach
((
scheme
)
=>
{
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'
));
lLimit
!==
null
&&
lLimit
!==
void
0
&&
data
.
push
(
markLineItem
(
'低限'
,
lLimit
,
'#fa8c16'
));
hLimit
!==
null
&&
hLimit
!==
void
0
&&
data
.
push
(
markLineItem
(
'高限'
,
hLimit
,
'#fa8c16'
));
hLimit
!==
null
&&
hLimit
!==
void
0
&&
data
.
push
(
markLineItem
(
'高限'
,
hLimit
,
'#fa8c16'
));
llLimit
!==
null
&&
llLimit
!==
void
0
&&
data
.
push
(
markLineItem
(
'低低限'
,
llLimit
,
'#FF0000'
));
llLimit
!==
null
&&
llLimit
!==
void
0
&&
data
.
push
(
markLineItem
(
'低低限'
,
llLimit
,
'#FF0000'
));
hhLimit
!==
null
&&
hhLimit
!==
void
0
&&
data
.
push
(
markLineItem
(
'高高限'
,
hhLimit
,
'#FF0000'
));
hhLimit
!==
null
&&
hhLimit
!==
void
0
&&
data
.
push
(
markLineItem
(
'高高限'
,
hhLimit
,
'#FF0000'
));
});
});
data
.
push
({
data
.
push
({
name
:
'平均线'
,
name
:
'平均线'
,
type
:
'average'
,
type
:
'average'
,
lineStyle
:
{
lineStyle
:
{
color
:
'#00b8b1'
,
color
:
'#00b8b1'
,
type
:
'solid'
,
type
:
'solid'
,
},
},
label
:
{
label
:
{
position
:
'insideEndTop'
,
position
:
'insideEndTop'
,
color
:
'#00b8b1'
,
color
:
'#00b8b1'
,
formatter
:
function
(
param
)
{
formatter
:
function
(
param
)
{
return
`平均值:
${
param
.
value
}
`
;
return
`平均值:
${
param
.
value
}
`
;
},
},
},
},
});
});
return
{
return
{
symbol
:
[
'none'
,
'none'
],
symbol
:
[
'none'
,
'none'
],
data
,
data
,
};
};
};
};
export
const
minMaxMarkPoint
=
(
dataItem
,
index
,
dataSource
)
=>
{
export
const
minMaxMarkPoint
=
(
dataItem
,
index
,
dataSource
)
=>
{
const
_isMobile
=
isMobile
();
const
_isMobile
=
isMobile
();
// 只有一个数据曲线时显示markline
// 只有一个数据曲线时显示markline
if
(
!
dataItem
||
dataSource
.
length
!==
1
)
return
{};
if
(
!
dataItem
||
dataSource
.
length
!==
1
)
return
{};
const
data
=
[
const
data
=
[
{
{
type
:
'min'
,
type
:
'min'
,
value
:
null
,
value
:
null
,
name
:
'最小: '
,
name
:
'最小: '
,
symbol
:
`image://
${
minIcon
}
`
,
symbol
:
`image://
${
minIcon
}
`
,
symbolOffset
:
[
0
,
18
],
symbolOffset
:
[
0
,
18
],
},
},
{
{
type
:
'max'
,
type
:
'max'
,
value
:
null
,
value
:
null
,
name
:
'最大: '
,
name
:
'最大: '
,
symbol
:
`image://
${
maxIcon
}
`
,
symbol
:
`image://
${
maxIcon
}
`
,
symbolOffset
:
[
0
,
-
16
],
symbolOffset
:
[
0
,
-
16
],
},
},
];
];
return
{
return
{
label
:
{
label
:
{
show
:
false
,
show
:
false
,
},
},
symbolSize
:
[
49
,
31
],
symbolSize
:
[
49
,
31
],
data
,
data
,
};
};
};
};
/**
/**
...
@@ -216,27 +216,27 @@ export const minMaxMarkPoint = (dataItem, index, dataSource) => {
...
@@ -216,27 +216,27 @@ export const minMaxMarkPoint = (dataItem, index, dataSource) => {
* @param {any} axis
* @param {any} axis
*/
*/
export
const
decorateAxisGridLine
=
(
axis
,
showGrid
)
=>
{
export
const
decorateAxisGridLine
=
(
axis
,
showGrid
)
=>
{
if
(
!
axis
)
return
;
if
(
!
axis
)
return
;
axis
.
minorTick
=
{
axis
.
minorTick
=
{
lineStyle
:
{
lineStyle
:
{
color
:
'#e2e2e2'
,
color
:
'#e2e2e2'
,
},
},
...(
axis
.
minorTick
||
{}),
...(
axis
.
minorTick
||
{}),
show
:
showGrid
,
show
:
showGrid
,
splitNumber
:
2
,
splitNumber
:
2
,
};
};
axis
.
minorSplitLine
=
{
axis
.
minorSplitLine
=
{
lineStyle
:
{
lineStyle
:
{
color
:
'#e2e2e2'
,
color
:
'#e2e2e2'
,
type
:
'dashed'
,
type
:
'dashed'
,
},
},
...(
axis
.
minorSplitLine
||
{}),
...(
axis
.
minorSplitLine
||
{}),
show
:
showGrid
,
show
:
showGrid
,
};
};
axis
.
splitLine
=
{
axis
.
splitLine
=
{
...(
axis
.
splitLine
||
{}),
...(
axis
.
splitLine
||
{}),
show
:
showGrid
,
show
:
showGrid
,
};
};
};
};
/**
/**
...
@@ -245,691 +245,710 @@ export const decorateAxisGridLine = (axis, showGrid) => {
...
@@ -245,691 +245,710 @@ export const decorateAxisGridLine = (axis, showGrid) => {
* @param {any} dataItem
* @param {any} dataItem
*/
*/
export
const
offlineArea
=
(
dataItem
)
=>
{
export
const
offlineArea
=
(
dataItem
)
=>
{
if
(
!
dataItem
)
return
{};
if
(
!
dataItem
)
return
{};
const
{
dataModel
}
=
dataItem
;
const
{
dataModel
}
=
dataItem
;
let
datas
=
new
Array
();
let
datas
=
new
Array
();
let
offlineData
=
[];
let
offlineData
=
[];
let
hasOffline
=
false
;
let
hasOffline
=
false
;
dataModel
.
forEach
((
item
,
index
)
=>
{
dataModel
.
forEach
((
item
,
index
)
=>
{
if
(
!
item
.
pv
&&
!
hasOffline
)
{
if
(
!
item
.
pv
&&
!
hasOffline
)
{
offlineData
=
[
offlineData
=
[
{
{
name
:
'离线'
,
name
:
'离线'
,
xAxis
:
new
Date
(
item
.
pt
),
xAxis
:
new
Date
(
item
.
pt
),
label
:
{
show
:
!
datas
?.
length
},
label
:
{
show
:
!
datas
?.
length
},
},
];
hasOffline
=
true
;
}
else
if
(
item
.
pv
&&
hasOffline
)
{
offlineData
.
push
({
xAxis
:
new
Date
(
item
.
pt
),
});
datas
.
push
(
offlineData
);
offlineData
=
[];
hasOffline
=
false
;
}
});
return
{
itemStyle
:
{
color
:
'#eee'
,
opacity
:
0.6
,
},
},
data
:
datas
,
];
};
hasOffline
=
true
;
}
else
if
(
item
.
pv
&&
hasOffline
)
{
offlineData
.
push
({
xAxis
:
new
Date
(
item
.
pt
),
});
datas
.
push
(
offlineData
);
offlineData
=
[];
hasOffline
=
false
;
}
});
return
{
itemStyle
:
{
color
:
'#eee'
,
opacity
:
0.6
,
},
data
:
datas
,
};
};
};
// tooltip 模板
// tooltip 模板
const
headTemplate
=
(
param
,
opt
)
=>
{
const
headTemplate
=
(
param
,
opt
)
=>
{
if
(
!
param
)
return
''
;
if
(
!
param
)
return
''
;
const
{
name
,
axisValueLabel
,
axisType
,
axisValue
}
=
param
;
const
{
name
,
axisValueLabel
,
axisType
,
axisValue
}
=
param
;
const
timeFormat
=
const
timeFormat
=
opt
&&
opt
.
contrast
opt
&&
opt
.
contrast
?
opt
.
contrastOption
===
'day'
?
opt
.
contrastOption
===
'day'
?
'HH:mm:ss'
?
'HH:mm:ss'
:
'DD日HH时'
:
'DD日HH时'
:
'YYYY-MM-DD HH:mm:ss'
;
:
'YYYY-MM-DD HH:mm:ss'
;
const
text
=
const
text
=
axisType
===
'xAxis.time'
?
moment
(
axisValue
).
format
(
timeFormat
)
:
name
||
axisValueLabel
;
axisType
===
'xAxis.time'
?
moment
(
axisValue
).
format
(
timeFormat
)
:
name
||
axisValueLabel
;
return
`<div style="border-bottom: 1px solid #F0F0F0; color: #808080; margin-bottom:
${
handlePx
(
return
`<div style="border-bottom: 1px solid #F0F0F0; color: #808080; margin-bottom:
${
handlePx
(
5
,
5
,
'px'
,
'px'
,
)}
; padding-bottom:
${
handlePx
(
5
,
'px'
)}
;">
${
text
}
</div>`
;
)}
; padding-bottom:
${
handlePx
(
5
,
'px'
)}
;">
${
text
}
</div>`
;
};
};
const
seriesTemplate
=
(
param
,
unit
)
=>
{
const
seriesTemplate
=
(
param
,
unit
)
=>
{
if
(
!
param
||
param
.
seriesName
===
'自定义'
)
return
''
;
if
(
!
param
||
param
.
seriesName
===
'自定义'
)
return
''
;
const
{
value
,
encode
}
=
param
;
const
{
value
,
encode
}
=
param
;
// const val = value[encode.y[0]];
// const val = value[encode.y[0]];
const
_unit
=
unit
||
''
;
const
_unit
=
unit
||
''
;
const
color
=
'#008CFF'
;
const
color
=
'#008CFF'
;
if
(
!
isArray
(
value
))
if
(
!
isArray
(
value
))
return
` <div style="display: flex; align-items: center;">
return
` <div style="display: flex; align-items: center;">
<span style="
${
isMobile
()
<span style="
${
?
'width: '
+
isMobile
()
handlePx
(
90
,
'px'
)
+
?
'width: '
+
';overflow:hidden;text-overflow:ellipsis;white-space:nowrap'
handlePx
(
90
,
'px'
)
+
:
''
';overflow:hidden;text-overflow:ellipsis;white-space:nowrap'
}
">
${
param
.
seriesName
}
</span>
:
''
}
">
${
param
.
seriesName
}
</span>
<span style="display:inline-block;">:</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;">
${
}
<
/span
>
value
?.
toFixed
(
3
)
??
'-'
}
<
/span
>
<
span
style
=
"font-size: ${handlePx(12, 'px')};"
>
$
{
_unit
??
''
}
<
/span
>
<
span
style
=
"font-size: ${handlePx(12, 'px')};"
>
$
{
_unit
??
''
}
<
/span
>
<
/div>`
;
<
/div>`
;
return
param
.
componentSubType
!==
'candlestick'
return
param
.
componentSubType
!==
'candlestick'
?
`<div style="display: flex; align-items: center;">
?
`<div style="display: flex; align-items: center;">
<span style="
${
isMobile
()
<span style="
${
?
'width: '
+
isMobile
()
handlePx
(
90
,
'px'
)
+
?
'width: '
+
';overflow:hidden;text-overflow:ellipsis;white-space:nowrap'
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
]
??
'-'
}
">
${
param
.
seriesName
}
</span><span style="display:inline-block;">:</span>
}
<
/span
>
<span style="color:
${
COLOR
.
AVG
}
;margin: 0
${
handlePx
(
5
,
'px'
)}
0 auto;">
${
value
[
1
]
??
'-'
}
<
/span
>
<
span
style
=
"font-size: ${handlePx(12, 'px')};"
>
$
{
_unit
??
''
}
<
/span
>
<
span
style
=
"font-size: ${handlePx(12, 'px')};"
>
$
{
_unit
??
''
}
<
/span
>
<
/div>
`
<
/div>
`
:
`
:
`
<div style="display: flex; align-items: center;">
<div style="display: flex; align-items: center;">
<span>首值</span><span style="display:inline-block;">:</span>
<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;">
${
}
<
/span
>
value
[
1
]
??
'-'
}
<
/span
>
<
span
style
=
"font-size: ${handlePx(12, 'px')};"
>
$
{
_unit
??
''
}
<
/span
>
<
span
style
=
"font-size: ${handlePx(12, 'px')};"
>
$
{
_unit
??
''
}
<
/span
>
<
/div
>
<
/div
>
<
div
style
=
"display: flex; align-items: center;"
>
<
div
style
=
"display: flex; align-items: center;"
>
<
span
>
尾值
<
/span><span style="display:inline-block;">:</
span
>
<
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;"
>
$
{
}
<
/span
>
value
[
2
]
??
'-'
}
<
/span
>
<
span
style
=
"font-size: ${handlePx(12, 'px')};"
>
$
{
_unit
??
''
}
<
/span
>
<
span
style
=
"font-size: ${handlePx(12, 'px')};"
>
$
{
_unit
??
''
}
<
/span
>
<
/div
>
<
/div
>
<
div
style
=
"display: flex; align-items: center;"
>
<
div
style
=
"display: flex; align-items: center;"
>
<
span
>
周期最小值
<
/span><span style="display:inline-block;">:</
span
>
<
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;"
>
$
{
}
<
/span
>
value
[
3
]
??
'-'
}
<
/span
>
<
span
style
=
"font-size: ${handlePx(12, 'px')};"
>
$
{
_unit
??
''
}
<
/span
>
<
span
style
=
"font-size: ${handlePx(12, 'px')};"
>
$
{
_unit
??
''
}
<
/span
>
<
/div
>
<
/div
>
<
div
style
=
"display: flex; align-items: center;"
>
<
div
style
=
"display: flex; align-items: center;"
>
<
span
>
周期最大值
<
/span><span style="display:inline-block;">:</
span
>
<
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;"
>
$
{
}
<
/span
>
value
[
4
]
??
'-'
}
<
/span
>
<
span
style
=
"font-size: ${handlePx(12, 'px')};"
>
$
{
_unit
??
''
}
<
/span
>
<
span
style
=
"font-size: ${handlePx(12, 'px')};"
>
$
{
_unit
??
''
}
<
/span
>
<
/div
>
<
/div
>
`;
`;
};
};
const tooltipAccessor = (unit, contrastOption) => {
const tooltipAccessor = (unit, contrastOption) => {
return {
return {
formatter: function (params, ticket, callback) {
formatter: function (params, ticket, callback) {
let tooltipHeader = '';
let tooltipHeader = '';
let tooltipContent = '';
let tooltipContent = '';
if (isArray(params)) {
if (isArray(params)) {
tooltipHeader = headTemplate(params[0], contrastOption);
tooltipHeader = headTemplate(params[0], contrastOption);
params.forEach((param) => {
params.forEach((param) => {
tooltipContent += seriesTemplate(param, unit?.[param?.seriesIndex]);
tooltipContent += seriesTemplate(param, unit?.[param?.seriesIndex]);
});
});
} else {
} else {
tooltipHeader = headTemplate(params, contrastOption);
tooltipHeader = headTemplate(params, contrastOption);
tooltipContent += seriesTemplate(params, unit?.[params?.seriesIndex]);
tooltipContent += seriesTemplate(params, unit?.[params?.seriesIndex]);
}
}
return `
return `
<
div
>
<
div
>
$
{
tooltipHeader
}
$
{
tooltipHeader
}
<
div
>
$
{
tooltipContent
}
<
/div
>
<
div
>
$
{
tooltipContent
}
<
/div
>
<
/div
>
<
/div
>
`;
`;
},
},
};
};
};
};
// 处理特殊业务:1. 频率;2. 是否在线(暂时不上)
// 处理特殊业务:1. 频率;2. 是否在线(暂时不上)
const handleSpecial1 = (special, dataSource) => {
const handleSpecial1 = (special, dataSource) => {
// 频率部分的业务
// 频率部分的业务
const _colorMap = {
const _colorMap = {
变频: '#1685ff',
变频: '#1685ff',
工频: '#00d0c7',
工频: '#00d0c7',
运行: '#1685ff',
运行: '#1685ff',
故障: '#ff6b37',
故障: '#ff6b37',
停止: '#666666',
停止: '#666666',
};
};
let _special1 = special?.special1 ?? {};
let _special1 = special?.special1 ?? {};
let _valDesc = _special1?.valDesc ?? {};
let _valDesc = _special1?.valDesc ?? {};
let _data = dataSource.find((item) => item.sensorName === _special1.name);
let _data = dataSource.find((item) => item.sensorName === _special1.name);
let _markAreaData = [];
let _markAreaData = [];
let _pieces =
let _pieces =
_data?.dataModel
_data?.dataModel
?.reduce((final, cur, index) => {
?.reduce((final, cur, index) => {
let _pt = moment(cur.pt).valueOf();
let _pt = moment(cur.pt).valueOf();
let _length = final.length;
let _length = final.length;
if (_colorMap[_valDesc[cur.pv]]) {
if (_colorMap[_valDesc[cur.pv]]) {
if (_length === 0) {
if (_length === 0) {
final.push({
final.push({
lte: _pt,
lte: _pt,
gte: 0,
gte: 0,
color: _colorMap[_valDesc[cur.pv]],
color: _colorMap[_valDesc[cur.pv]],
value: cur.pv,
value: cur.pv,
text: _valDesc[cur.pv],
text: _valDesc[cur.pv],
});
});
} else {
} else {
if (cur.pv === final[_length - 1].value) {
if (cur.pv === final[_length - 1].value) {
final[_length - 1].lte = _pt;
final[_length - 1].lte = _pt;
} else {
} else {
final.push({
final.push({
lte: _pt,
lte: _pt,
gte: _pt,
gte: final[_length - 1].gte,
color: _colorMap[_valDesc[cur.pv]],
color: _colorMap[_valDesc[cur.pv]],
value: cur.pv,
value: cur.pv,
text: _valDesc[cur.pv],
text: _valDesc[cur.pv],
});
});
}
}
}
}
}
}
return final;
return final;
}, [])
}, [])
.map((item) => {
.map((item) => {
_markAreaData.push([
_markAreaData.push([
{
{
xAxis: item.gte,
xAxis: item.gte,
itemStyle: {
// color: item.color
color: {
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{
offset: 0,
color: item.color, // 0% 处的颜色
},
{
offset: 1,
color: item.color, // 100% 处的颜色
},
],
global: false, // 缺省为 false
},
},
name: item.text,
label: {show: true},
},
{
xAxis: item.lte,
itemStyle: {
color: item.color,
},
},
]);
delete item.value;
return item;
}) ?? [];
let _final = {};
if (_markAreaData.length) {
_final.visualMap = {
type: 'piecewise',
show: false,
dimension: 0,
seriesIndex: 0,
pieces: _pieces,
};
}
if (_pieces.length) {
_final.markArea = {
silent: true,
itemStyle: {
itemStyle: {
opacity: 0.1,
// color: item.color
color: {
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{
offset: 0,
color: item.color, // 0% 处的颜色
},
{
offset: 1,
color: item.color, // 100% 处的颜色
},
],
global: false, // 缺省为 false
},
},
},
data: _markAreaData,
name: item.text,
};
label: { show: true },
}
},
return _final;
{
xAxis: item.lte,
itemStyle: {
color: item.color,
},
},
]);
delete item.value;
return item;
}) ?? [];
let _final = {};
if (_markAreaData.length) {
_final.visualMap = {
type: 'piecewise',
show: false,
dimension: 0,
seriesIndex: 0,
pieces: _pieces,
};
}
if (_pieces.length) {
_final.markArea = {
silent: true,
itemStyle: {
opacity: 0.1,
},
data: _markAreaData,
};
}
return _final;
};
};
// 生成x坐标
// 生成x坐标
const returnXAxis = ({
const returnXAxis = ({
dataSource,
dataSource,
contrast,
contrast,
contrastOption,
contrastOption,
nameWithSensor,
nameWithSensor,
showMarkLine,
showMarkLine,
deviceAlarmSchemes,
deviceAlarmSchemes,
showPoint,
showPoint,
restOption,
restOption,
smooth,
smooth,
special,
special,
yAxis
yAxis,
}) => {
}) => {
// 根据"指标名称"分类yAxis
// 根据"指标名称"分类yAxis
const yAxisInterator = (() => {
const yAxisInterator = (() => {
const map = new Map();
const map = new Map();
let current = -1;
let current = -1;
const get = (name) => (map.has(name) ? map.get(name) : map.set(name, ++current).get(name));
const get = (name) => (map.has(name) ? map.get(name) : map.set(name, ++current).get(name));
return {get
};
return { get
};
})();
})();
let _offlineData = [];
let _offlineData = [];
// 生成visualMap、markArea
// 生成visualMap、markArea
let {visualMap, markArea
} = handleSpecial1(special, dataSource);
let { visualMap, markArea
} = handleSpecial1(special, dataSource);
let _filterArr = ['是否在线'];
let _filterArr = ['是否在线'];
if (special?.special1?.name) {
if (special?.special1?.name) {
_filterArr.push(special.special1.name);
_filterArr.push(special.special1.name);
}
}
// 生成series
// 生成series
let series = dataSource
let series = dataSource
.filter((item) => {
.filter((item) => {
if (item.sensorName === '是否在线') {
if (item.sensorName === '是否在线') {
_offlineData.push(item);
_offlineData.push(item);
}
}
return !_filterArr.includes(item.sensorName);
return !_filterArr.includes(item.sensorName);
})
})
.map((item, index) => {
.map((item, index) => {
const {sensorName, unit
} = item;
const { sensorName, unit
} = item;
const name = nameFormatter(item, contrast, contrastOption, nameWithSensor);
const name = nameFormatter(item, contrast, contrastOption, nameWithSensor);
const data = dataAccessor(item, contrast, contrastOption);
const data = dataAccessor(item, contrast, contrastOption);
const type = 'line';
const type = 'line';
const areaStyle = areaStyleFormatter(item);
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 yAxisIndex = _index > -1 ? _index : 0;
const markLine = showMarkLine
const markLine = showMarkLine
? alarmMarkLine(item, index, dataSource, deviceAlarmSchemes)
? alarmMarkLine(item, index, dataSource, deviceAlarmSchemes)
: {};
: {};
const markPoint = showPoint ? minMaxMarkPoint(item, index, dataSource) : {};
const markPoint = showPoint ? minMaxMarkPoint(item, index, dataSource) : {};
// let markArea = null;
// let markArea = null;
// 需求变更:设备离线改用“是否在线”的数据,离线的状态标记的数据用该部分的数据。 2023年4月25日09:36:55
// 需求变更:设备离线改用“是否在线”的数据,离线的状态标记的数据用该部分的数据。 2023年4月25日09:36:55
// 暂时注释,离线逻辑需要再确认 2023-09-15
// 暂时注释,离线逻辑需要再确认 2023-09-15
/* let _offlineAreasData = _offlineData
/* let _offlineAreasData = _offlineData
.find((offline) => offline.stationCode === item.stationCode);
.find((offline) => offline.stationCode === item.stationCode);
let offlineAreas = offlineArea(_offlineAreasData);
let offlineAreas = offlineArea(_offlineAreasData);
if (offlineAreas.data?.length) {
if (offlineAreas.data?.length) {
restOption.markArea = null;
restOption.markArea = null;
markArea = offlineAreas;
markArea = offlineAreas;
}*/
}*/
// 需求新增:增加频率业务
// 需求新增:增加频率业务
return {
return {
notMerge: true,
notMerge: true,
name,
name,
type,
type,
data,
data,
areaStyle,
areaStyle,
yAxisIndex,
yAxisIndex,
smooth,
smooth,
unit,
unit,
markLine,
markLine,
markPoint,
markPoint,
markArea,
markArea,
};
};
});
});
// 由于series更新后,没有的数据曲线仍然停留在图表区上,导致图表可视区范围有问题
// 由于series更新后,没有的数据曲线仍然停留在图表区上,导致图表可视区范围有问题
const min = Math.min(
const min = Math.min(
...series.map((item) => item.data?.[0]?.[0]).filter((item) => item !== undefined),
...series.map((item) => item.data?.[0]?.[0]).filter((item) => item !== undefined),
);
);
const max = Math.max(
const max = Math.max(
...series
...series
.map((item) => item.data?.[item.data.length - 1]?.[0])
.map((item) => item.data?.[item.data.length - 1]?.[0])
.filter((item) => item !== undefined),
.filter((item) => item !== undefined),
);
);
return {
return {
xAxis: {
xAxis: {
type: 'time',
type: 'time',
min,
min,
max,
max,
axisLabel: {
axisLabel: {
formatter: contrast
formatter: contrast
? contrastOption === 'month'
? contrastOption === 'month'
? '{dd}日'
? '{dd}日'
: '{HH}:{mm}'
: '{HH}:{mm}'
: {
: {
year: '{yyyy}',
year: '{yyyy}',
month: '{MMM}',
month: '{MMM}',
day: '{d}日',
day: '{d}日',
hour: '{HH}:{mm}',
hour: '{HH}:{mm}',
minute: '{HH}:{mm}',
minute: '{HH}:{mm}',
second: '{HH}:{mm}:{ss}',
second: '{HH}:{mm}:{ss}',
none: '{yyyy}-{MM}-{dd} {hh}:{mm}:{ss}',
none: '{yyyy}-{MM}-{dd} {hh}:{mm}:{ss}',
},
},
},
},
},
series,
},
visualMap,
series,
};
visualMap,
};
};
};
const handleDefault = (config, cusOption) => {
const handleDefault = (config, cusOption) => {
const needUnit = _.get(config, 'needUnit', false);
const needUnit = _.get(config, 'needUnit', false);
const curveCenter = _.get(config, 'curveCenter', false);
const curveCenter = _.get(config, 'curveCenter', false);
const nameWithSensor = _.get(config, 'nameWithSensor', true);
const nameWithSensor = _.get(config, 'nameWithSensor', true);
const showGridLine = _.get(config, 'showGridLine', true);
const showGridLine = _.get(config, 'showGridLine', true);
const showMarkLine = _.get(config, 'showMarkLine', false);
const showMarkLine = _.get(config, 'showMarkLine', false);
const showPoint = _.get(config, 'showPoint', false);
const showPoint = _.get(config, 'showPoint', false);
const deviceAlarmSchemes = _.get(config, 'deviceAlarmSchemes', []);
const deviceAlarmSchemes = _.get(config, 'deviceAlarmSchemes', []);
const chartType = _.get(config, 'chartType', null);
const chartType = _.get(config, 'chartType', null);
const showBoxOption = _.get(config, 'showBoxOption', false);
const showBoxOption = _.get(config, 'showBoxOption', false);
// 自定义属性
// 自定义属性
const restOption = _.pick(cusOption, ['title', 'legend']);
const restOption = _.pick(cusOption, ['title', 'legend']);
const special = _.get(config, 'special', {});
const special = _.get(config, 'special', {});
return {
return {
needUnit,
needUnit,
curveCenter,
curveCenter,
nameWithSensor,
nameWithSensor,
showGridLine,
showGridLine,
showMarkLine,
showMarkLine,
showPoint,
showPoint,
deviceAlarmSchemes,
deviceAlarmSchemes,
chartType,
chartType,
showBoxOption,
showBoxOption,
restOption,
restOption,
special,
special,
};
};
};
};
const handleMaxValue = (value) => {
const handleMaxValue = (value) => {
if (value <= 1) return value.toFixed(2);
if (value <= 1) return value.toFixed(2);
if (value >= 100000) return `
$
{(
value
/
1000
).
toFixed
(
2
)}
k
`;
if (value >= 100000) return `
$
{(
value
/
1000
).
toFixed
(
2
)}
k
`;
return value.toFixed(2);
return value.toFixed(2);
}
}
;
const reduceYAxis = (arr, dataSource) => {
const reduceYAxis = (arr, dataSource) => {
let _offsetValue = [];
let _offsetValue = [];
// 1. 合并相同单位的坐标轴
// 1. 合并相同单位的坐标轴
let _arr = arr.reduce((final, cur) => {
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]) {
if (!final[_key]) {
final[_key] = cur
final[_key] = cur;
}
}
return final;
}, {});
// 2. 合并相同单位的数据,找出最大值
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);
// 2. 合并相同单位的数据,找出最大值
if (final[_key] === undefined) {
let _maxValueArr = Object.values(dataSource.reduce((final, cur) => {
final[_key] = _maxValue;
let _key = cur.sensorName === null ? 'null' : cur.sensorName;
} else {
let _maxValue = cur.dataModel.reduce((final, cur) => {
final[_key] = Math.max([final[_key], _maxValue]);
// eslint-disable-next-line no-param-reassign
}
if (cur.pv > final) final = cur.pv;
return final;
return final
}, {}),
}, 0);
);
if (final[_key] === undefined) {
// 3. 合并,生成Y轴配置
final[_key] = _maxValue
return Object.values(_arr).map((item, index) => {
} else {
let _key = item.name === null ? 'null' : item.name;
final[_key] = Math.max([final[_key], _maxValue]);
let _lastAxisNumber = _maxValueArr[index - 2];
}
let _baseOffset = _offsetValue[index - 2] ?? 0;
return final
let _finalOffset =
}, {}));
(_lastAxisNumber !== undefined // 没有相邻的轴
// 3. 合并,生成Y轴配置
? (_lastAxisNumber === 0 ? 20 : _lastAxisNumber.toFixed(2).replaceAll('.', '').length) * 12
return Object.values(_arr).map((item, index) => {
: 0) + _baseOffset;
let _key = item.name === null ? 'null' : item.name;
_offsetValue.push(_finalOffset);
let _lastAxisNumber = _maxValueArr[index - 2];
return {
let _baseOffset = _offsetValue[index - 2] ?? 0;
...item,
let _finalOffset = (
offset: _finalOffset,
_lastAxisNumber !== undefined ? // 没有相邻的轴
position: index % 2 === 0 ? 'left' : 'right',
(_lastAxisNumber === 0 ? 20 : _lastAxisNumber.toFixed(2).replaceAll('.', '').length) * 12
nameTextStyle: {
: 0
align: index % 2 === 0 ? 'right' : 'left',
) + _baseOffset;
},
_offsetValue.push(_finalOffset);
};
return ({
});
...item,
offset: _finalOffset,
position: index % 2 === 0 ? 'left' : 'right',
nameTextStyle: {
align: index % 2 === 0 ? 'right' : 'left',
},
})
});
};
};
/**
/**
* 1. 生成常规的yAxis配置; 2. 处理sensorType为状态值的指标,生成yAxis配置
*
*
* 1. 生成常规的yAxis配置;
* @param {array} dataSource 数据源
* 2. 处理sensorType为状态值的指标,生成yAxis配置
* @param {boolean} needUnit 是否显示单位。
*
* @param {boolean} curveCenter 曲线是否居中。
* @param {array} dataSource 数据源
* @param {boolean} showGridLine 是否显示网格线。
* @param {boolean} needUnit 是否显示单位。
* @returns {object} 返回左右轴的margin、yAxis的配置。
* @param {boolean} curveCenter 曲线是否居中。
*/
* @param {boolean} showGridLine 是否显示网格线。
const handleYAxis = ({ dataSource, needUnit, curveCenter, showGridLine }) => {
* @return {object} 返回左右轴的margin、yAxis的配置。
const yAxisMap = new Map();
* */
// 1. 找出最大值; 2. 计算出y轴最大宽度动态计算偏移距离;
const handleYAxis = ({dataSource, needUnit, curveCenter, showGridLine}) => {
dataSource.forEach((item, index) => {
const yAxisMap = new Map();
const { sensorName, unit } = item;
// 1. 找出最大值; 2. 计算出y轴最大宽度动态计算偏移距离;
const key = sensorName;
dataSource.forEach((item, index) => {
if (!yAxisMap.has(key)) {
const {sensorName, unit} = item;
const axis = {
const key = sensorName;
type: 'value',
if (!yAxisMap.has(key)) {
name: needUnit ? unit : null,
const axis = {
axisLabel: {
type: 'value',
formatter: (value) => {
name: needUnit ? unit : null,
return handleMaxValue(value);
axisLabel: {
},
formatter: (value) => {
},
return handleMaxValue(value);
axisLine: {
}
show: true,
},
},
axisLine: {
minorTick: {
show: true,
lineStyle: {
},
color: '#e2e2e2',
minorTick: {
},
lineStyle: {
},
color: '#e2e2e2',
minorSplitLine: {
},
lineStyle: {
},
color: '#e2e2e2',
minorSplitLine: {
type: 'dashed',
lineStyle: {
},
color: '#e2e2e2',
},
type: 'dashed',
};
},
yAxisMap.set(key, axis);
},
}
};
// 曲线居中
yAxisMap.set(key, axis);
if (curveCenter && item.dataModel && item.dataModel.length > 0) {
}
const [min, max] = minMax(item);
// 曲线居中
const axis = yAxisMap.get(key);
if (curveCenter && item.dataModel && item.dataModel.length > 0) {
axis.min = axis.min === void 0 ? min : Math.min(min, axis.min);
const [min, max] = minMax(item);
axis.max = axis.max === void 0 ? max : Math.max(max, axis.max);
const axis = yAxisMap.get(key);
}
axis.min = axis.min === void 0 ? min : Math.min(min, axis.min);
// 网格显示
axis.max = axis.max === void 0 ? max : Math.max(max, axis.max);
const axis = yAxisMap.get(key);
}
decorateAxisGridLine(axis, showGridLine);
// 网格显示
});
const axis = yAxisMap.get(key);
const yAxis =
decorateAxisGridLine(axis, showGridLine);
yAxisMap.size > 0 ? reduceYAxis([...yAxisMap.values()], dataSource) : { type: 'value' };
});
const leftNum = Math.ceil(yAxisMap.size / 2);
const yAxis = yAxisMap.size > 0 ? reduceYAxis([...yAxisMap.values()], dataSource) : {type: 'value'};
const rightNum = Math.floor(yAxisMap.size / 2);
const leftNum = Math.ceil(yAxisMap.size / 2);
return { leftNum, rightNum, yAxis };
const rightNum = Math.floor(yAxisMap.size / 2);
return {leftNum, rightNum, yAxis};
};
};
/**
/**
*
1. 最后的配置处理、合并
* 1. 最后的配置处理、合并
* dataZoom 缩放
* dataZoom 缩放
* xAxis.minInterval X轴的最小间隔
* xAxis.minInterval X轴的最小间隔
* legend legend配置
* legend legend配置
* @param {object} restOption 额外配置
*
* @param {object} xAxis x轴的配置
* @param {object} restOption 额外配置
* @param {array} legendData legend数组
* @param {object} xAxis X轴的配置
* @param {string} chartType 线型 lineChart|boxChart
* @param {array} legendData Legend数组
* @param {boolean} contrast 是否为同期对比
* @param {string} chartType 线型 lineChart|boxChart
* @param {string} contrastOption 同期对比周期配置, day|month
* @param {boolean} contrast 是否为同期对比
* @param {object} config 其他的配置
* @param {string} contrastOption 同期对比周期配置, day|month
* */
* @param {object} config 其他的配置
const assignOptions = (restOption, xAxis, legendData, chartType, contrast, contrastOption, config) => {
*/
restOption.dataZoom = [
const assignOptions = (
{
restOption,
show: true,
xAxis,
bottom: 20,
legendData,
start: 0,
chartType,
end: 100,
contrast,
height: config.isMultiple ? 20 : 28,
contrastOption,
type: 'inside',
config,
zoomOnMouseWheel: true,
) => {
filterMode: chartType === 'lineChart' ? 'none' : 'weakFilter',
restOption.dataZoom = [
},
{
{
show: true,
show: true,
bottom: 20,
bottom: 20,
start: 0,
start: 0,
end: 100,
end: 100,
height: config.isMultiple ? 20 : 28,
height: config.isMultiple ? 20 : 28,
type: 'inside',
type: 'slider',
zoomOnMouseWheel: true,
zoomOnMouseWheel: true,
filterMode: chartType === 'lineChart' ? 'none' : 'weakFilter',
labelFormatter: function (e) {
},
let _formatterStr = 'YYYY-MM-DD HH:mm:ss';
{
if (contrast) {
show: true,
if (contrastOption === 'day') _formatterStr = 'HH:mm';
bottom: 20,
if (contrastOption === 'month') _formatterStr = 'MM月DD日 HH时';
start: 0,
}
end: 100,
return moment(e).format(_formatterStr);
height: config.isMultiple ? 20 : 28,
},
type: 'slider',
},
zoomOnMouseWheel: true,
];
labelFormatter: function (e) {
xAxis.minInterval = 3600 * (1 * 1000);
let _formatterStr = 'YYYY-MM-DD HH:mm:ss';
if (legendData) {
if (contrast) {
restOption.legend = {
if (contrastOption === 'day') _formatterStr = 'HH:mm';
...{
if (contrastOption === 'month') _formatterStr = 'MM月DD日 HH时';
show: true,
}
right:10,
return moment(e).format(_formatterStr);
top: 30,
},
icon: 'rect',
},
itemWidth: 14,
];
itemHeight: 8,
xAxis.minInterval = 3600 * (1 * 1000);
itemGap: 20,
if (legendData) {
}, ...restOption.legend, ...{data: legendData}
restOption.legend = {
};
...{
}
show: true,
right: 10,
top: 30,
icon: 'rect',
itemWidth: 14,
itemHeight: 8,
itemGap: 20,
},
...restOption.legend,
...{ data: legendData },
};
}
};
};
const returnMaxOrMinNumber = (dataSource, type) => {
const returnMaxOrMinNumber = (dataSource, type) => {
let _obj = null;
let _obj = null;
if (type === 'period' && dataSource?.[0]?.dataModel?.length) {
if (type === 'period' && dataSource?.[0]?.dataModel?.length) {
let _length = dataSource?.[0]?.dataModel?.length;
let _length = dataSource?.[0]?.dataModel?.length;
let _first = dataSource?.[0]?.dataModel[0]?.pt;
let _first = dataSource?.[0]?.dataModel[0]?.pt;
let _last = dataSource?.[0]?.dataModel[_length - 1]?.pt;
let _last = dataSource?.[0]?.dataModel[_length - 1]?.pt;
return ['展示时段: ', _first, _last, type];
return ['展示时段: ', _first, _last, type];
}
}
dataSource?.[0]?.dataModel
dataSource?.[0]?.dataModel
.filter((item) => item.pv !== null)
.filter((item) => item.pv !== null)
.forEach((item) => {
.forEach((item) => {
if (!_obj) {
if (!_obj) {
_obj = item;
_obj = item;
} else {
} else {
if (type === 'min') {
if (type === 'min') {
if (item.pv < _obj.pv) {
if (item.pv < _obj.pv) {
_obj = item;
_obj = item;
}
}
}
}
if (type === 'max') {
if (type === 'max') {
if (item.pv > _obj.pv) {
if (item.pv > _obj.pv) {
_obj = item;
_obj = item;
}
}
}
}
}
}
});
});
let _value = [];
let _value = [];
if (_obj?.pt) {
if (_obj?.pt) {
_value = [moment(_obj.pt).valueOf(), _obj.pv];
_value = [moment(_obj.pt).valueOf(), _obj.pv];
let _img = type === 'max' ? maxIcon : minIconDownArrow;
let _img = type === 'max' ? maxIcon : minIconDownArrow;
_value.push(_img);
_value.push(_img);
_value.push(type);
_value.push(type);
// 把最大值最小值都push进去,方便计算
// 把最大值最小值都push进去,方便计算
}
}
return _value;
return _value;
};
};
const handleGrid = (dataSource, needUnit, leftNum, rightNum, chartType) => {
const handleGrid = (dataSource, needUnit, leftNum, rightNum, chartType) => {
// 如果是单曲线,_grid的top需要一行的高度,用来放置最值最小值
// 如果是单曲线,_grid的top需要一行的高度,用来放置最值最小值
let _base = 60;
let _base = 60;
let _topForUnit = needUnit ? 20 : 0;
let _topForUnit = needUnit ? 20 : 0;
return {
return {
top: _base + _topForUnit,
top: _base + _topForUnit,
left: 30,
left: 30,
right: 10,
right: 10,
bottom: 60,
bottom: 60,
containLabel: true,
containLabel: true,
};
};
};
};
const renderItem = (params, api) => {
const renderItem = (params, api) => {
let _base = params.dataIndex;
let _base = params.dataIndex;
let _baseChartWidth = 10;
let _baseChartWidth = 10;
let _numberStringWidth =
let _numberStringWidth =
_base === 1 && api.value(3) === 'max'
_base === 1 && api.value(3) === 'max'
? String(api.value(4) || 0).length * _baseChartWidth
? String(api.value(4) || 0).length * _baseChartWidth
: String(api.value(1)).length * _baseChartWidth;
: String(api.value(1)).length * _baseChartWidth;
let _left = 30;
let _left = 30;
let _baseWidth = 190 + _numberStringWidth;
let _baseWidth = 190 + _numberStringWidth;
let _imgWidth = 45;
let _imgWidth = 45;
let _dateWidth = 128;
let _dateWidth = 128;
let _imageX = _left + _base * _baseWidth;
let _imageX = _left + _base * _baseWidth;
let _timeX = _left + _base * _baseWidth + _imgWidth;
let _timeX = _left + _base * _baseWidth + _imgWidth;
let _valueX = _left + _base * _baseWidth + _imgWidth + _dateWidth;
let _valueX = _left + _base * _baseWidth + _imgWidth + _dateWidth;
let _color = api.value(3) === 'min' ? '#05C2BC' : '#1685FF';
let _color = api.value(3) === 'min' ? '#05C2BC' : '#1685FF';
let topValue = 25;
let topValue = 25;
let _trimmer = -2;
let _trimmer = -2;
return {
return {
type: 'group',
type: 'group',
children: [
children: [
{
{
type: 'image',
type: 'image',
style: {
style: {
image: api.value(2),
image: api.value(2),
textVerticalAlign: 'middle',
textVerticalAlign: 'middle',
y: -6,
y: -6,
},
},
position: [_imageX, topValue],
position: [_imageX, topValue],
},
},
{
{
type: 'text',
type: 'text',
style: {
style: {
text: moment(api.value(0)).format('YYYY-MM-DD HH:mm:ss') + ': ',
text: moment(api.value(0)).format('YYYY-MM-DD HH:mm:ss') + ': ',
textVerticalAlign: 'top',
textVerticalAlign: 'top',
},
},
position: [_timeX, topValue + _trimmer],
position: [_timeX, topValue + _trimmer],
},
},
{
{
type: 'text',
type: 'text',
style: {
style: {
text: api.value(1),
text: api.value(1),
textVerticalAlign: 'middle',
textVerticalAlign: 'middle',
fill: _color,
fill: _color,
font: 'bolder 16px cursive',
font: 'bolder 16px cursive',
lineWidth: 10,
lineWidth: 10,
y: 3,
y: 3,
},
},
position: [_valueX, topValue + _trimmer],
position: [_valueX, topValue + _trimmer],
},
},
],
],
};
};
};
};
const returnCustomSeries = (dataSource) => {
const returnCustomSeries = (dataSource) => {
let _maxNumber = returnMaxOrMinNumber(dataSource, 'max');
let _maxNumber = returnMaxOrMinNumber(dataSource, 'max');
let _minNumber = returnMaxOrMinNumber(dataSource, 'min');
let _minNumber = returnMaxOrMinNumber(dataSource, 'min');
// let _period = returnMaxOrMinNumber(dataSource, 'period');
// let _period = returnMaxOrMinNumber(dataSource, 'period');
// 需要将最大值最小分别传入,后续计算图例位置需要,先min后max
// 需要将最大值最小分别传入,后续计算图例位置需要,先min后max
let _max = _maxNumber[1];
let _max = _maxNumber[1];
let _min = _minNumber[1];
let _min = _minNumber[1];
[_maxNumber, _minNumber].forEach((item) => {
[_maxNumber, _minNumber].forEach((item) => {
item.push(_min);
item.push(_min);
item.push(_max);
item.push(_max);
});
});
return {
return {
name: '自定义',
name: '自定义',
type: 'custom',
type: 'custom',
renderItem: renderItem,
renderItem: renderItem,
data: [_minNumber, _maxNumber],
data: [_minNumber, _maxNumber],
};
};
};
};
const renderStatusItem = (params, api) => {
const renderStatusItem = (params, api) => {
var categoryIndex = api.value(0);
var categoryIndex = api.value(0);
var start = api.coord([api.value(1), categoryIndex]);
var start = api.coord([api.value(1), categoryIndex]);
var end = api.coord([api.value(2), categoryIndex]);
var end = api.coord([api.value(2), categoryIndex]);
var height = api.size([0, 1])[1] * 0.4;
var height = api.size([0, 1])[1] * 0.4;
var rectShape = echarts.graphic.clipRectByRect(
var rectShape = echarts.graphic.clipRectByRect(
{
{
x: start[0],
x: start[0],
y: start[1] - height / 2,
y: start[1] - height / 2,
width: end[0] - start[0],
width: end[0] - start[0],
height: height
height: height,
},
},
{
{
x: params.coordSys.x,
x: params.coordSys.x,
y: params.coordSys.y,
y: params.coordSys.y,
width: params.coordSys.width,
width: params.coordSys.width,
height: params.coordSys.height
height: params.coordSys.height,
}
},
);
);
return (
return (
rectShape && {
rectShape && {
type: 'rect',
type: 'rect',
transition: ['shape'],
transition: ['shape'],
shape: rectShape,
shape: rectShape,
style: api.style()
style: api.style(),
}
}
);
);
}
}
;
/**
/**
* 图表配置项生成
* 图表配置项生成
...
@@ -943,440 +962,455 @@ const renderStatusItem = (params, api) => {
...
@@ -943,440 +962,455 @@ const renderStatusItem = (params, api) => {
*/
*/
const optionGenerator = (
const optionGenerator = (
dataSource,
cusOption,
contrast,
contrastOption,
smooth,
config,
lineDataType = '',
) => {
// 1. 处理配置,配置分配默认值;
const {
needUnit,
curveCenter,
nameWithSensor,
showGridLine,
showMarkLine,
showPoint,
deviceAlarmSchemes,
chartType,
showBoxOption,
restOption,
special,
} = handleDefault(config, cusOption);
const { leftNum, rightNum, yAxis } = handleYAxis({
dataSource,
needUnit,
curveCenter,
showGridLine,
});
let { xAxis, series, visualMap } = returnXAxis({
dataSource,
dataSource,
cusOption,
contrast,
contrast,
contrastOption,
contrastOption,
nameWithSensor,
showMarkLine,
deviceAlarmSchemes,
showPoint,
smooth,
smooth,
config,
restOption,
lineDataType = '',
special,
) => {
yAxis,
// 1. 处理配置,配置分配默认值;
});
const {
// 3. 判断是否开启网格;
needUnit,
const grid = handleGrid(dataSource, needUnit, leftNum, rightNum, chartType);
curveCenter,
decorateAxisGridLine(xAxis, showGridLine);
nameWithSensor,
const tooltipTimeFormat = !contrast
showGridLine,
? 'YYYY-MM-DD HH:mm:ss'
showMarkLine,
: contrastOption === 'day'
showPoint,
? 'HH:mm'
deviceAlarmSchemes,
: 'DD HH:mm';
chartType,
let tooltip = {};
showBoxOption,
// 增加箱线图的逻辑,单曲线才存在该逻辑
restOption,
if (chartType && showBoxOption && !special?.special1?.name) {
special,
if (chartType === 'boxChart' && lineDataType === '特征曲线') {
} = handleDefault(config, cusOption);
const otherData =
const {leftNum, rightNum, yAxis} = handleYAxis({
dataSource?.[0]?.dataModel.map((item) => {
dataSource,
const { firstPV, lastPV, maxPV, minPV, pt } = item;
needUnit,
return [moment(pt).valueOf(), firstPV, lastPV, minPV, maxPV];
curveCenter,
}) || []; //当存在othersData的时候,只是单曲线
showGridLine,
xAxis = { type: 'time' };
});
decorateAxisGridLine(xAxis, showGridLine);
let {xAxis, series, visualMap} = returnXAxis({
let unit = [];
dataSource,
series = series.map((item) => {
contrast,
if (item.unit) unit.push(item.unit);
contrastOption,
item.areaStyle = null;
nameWithSensor,
return { ...item, showSymbol: false };
showMarkLine,
});
deviceAlarmSchemes,
// 箱线图去除曲线 2023年10月17日
showPoint,
series = [
smooth,
{
restOption,
type: 'candlestick',
special,
name: '箱线图',
yAxis
symbol: 'none',
});
data: otherData,
// 3. 判断是否开启网格;
itemStyle: {
const grid = handleGrid(dataSource, needUnit, leftNum, rightNum, chartType);
color: '#FFA200',
decorateAxisGridLine(xAxis, showGridLine);
color0: '#44CD00',
const tooltipTimeFormat = !contrast
borderColor: '#FFA200',
? 'YYYY-MM-DD HH:mm:ss'
borderColor0: '#44CD00',
: contrastOption === 'day'
},
? 'HH:mm'
},
: 'DD HH:mm';
];
let tooltip = {};
tooltip = tooltipAccessor(unit);
// 增加箱线图的逻辑,单曲线才存在该逻辑
}
if (chartType && showBoxOption && !special?.special1?.name) {
if (chartType === 'lineChart' || lineDataType === '原始曲线') {
if (chartType === 'boxChart' && lineDataType === '特征曲线') {
let _maxData = [];
const otherData =
let _minData = [];
dataSource?.[0]?.dataModel.map((item) => {
let _currentYear = moment().format('YYYY');
const {firstPV, lastPV, maxPV, minPV, pt} = item;
const formatStr =
return [moment(pt).valueOf(), firstPV, lastPV, minPV, maxPV];
contrastOption === 'day'
}) || []; //当存在othersData的时候,只是单曲线
? `
$
{
_currentYear
}
-
01
-
01
HH
:
mm
:
00
`
xAxis = {type: 'time'};
: `
$
{
_currentYear
}
-
01
-
DD
HH
:
mm
:
00
`; // 用来做同期对比,把日期拉到同一区间
decorateAxisGridLine(xAxis, showGridLine);
let _maxValues = [];
let unit = [];
/** 生成泳道图,分两种情况 1. 当最大值最小值都是正数时; 2. 当最大值小于零时(此时,最小值一定小于零); */
series = series.map((item) => {
dataSource?.[0]?.dataModel.forEach((item) => {
if (item.unit) unit.push(item.unit);
const { firstPV, lastPV, maxPV, minPV, pt } = item;
item.areaStyle = null;
_maxValues.push(maxPV);
return {...item, showSymbol: false};
let time = contrast ? moment(pt).format(formatStr) : pt;
});
_maxData.push([
// 箱线图去除曲线 2023年10月17日
moment(time).valueOf(),
series=[{
(maxPV > 0 ? maxPV - minPV : minPV - maxPV).toFixed(2),
type: 'candlestick',
]);
name: '箱线图',
_minData.push([moment(time).valueOf(), maxPV > 0 ? minPV : maxPV]);
symbol: 'none',
}); //当存在othersData的时候,只是单曲线
data: otherData,
// xAxis = {type: 'category', data: series[0].data.map(item => moment(item[0]).format('YYYY-MM-DD HH:mm:ss'))};
itemStyle: {
xAxis = { type: 'time' };
color: '#FFA200',
decorateAxisGridLine(xAxis, showGridLine);
color0: '#44CD00',
let _unit = '';
borderColor: '#FFA200',
series = series.map((item) => {
borderColor0: '#44CD00',
_unit = item.unit ?? '';
item.areaStyle = null;
return { ...item, showSymbol: false };
});
[[..._minData], [..._maxData]].forEach((item, index) => {
series.push({
name: index === 0 ? '周期最小值' : '周期最大值',
type: 'line',
data: item,
lineStyle: {
opacity: 0,
},
...(index !== 0
? {
areaStyle: {
color: series?.[0]?.itemStyle?.color ?? '#65a0d1',
opacity: 0.2,
},
},
}];
}
tooltip = tooltipAccessor(unit);
: {}),
}
stack: 'confidence-band',
if (chartType === 'lineChart' || lineDataType === '原始曲线') {
symbol: 'none',
let _maxData = [];
});
let _minData = [];
});
let _currentYear = moment().format('YYYY');
tooltip = {
const formatStr =
trigger: 'axis',
contrastOption === 'day'
formatter: (e) => {
? `
$
{
_currentYear
}
-
01
-
01
HH
:
mm
:
00
`
return `
<
div
>
: `
$
{
_currentYear
}
-
01
-
DD
HH
:
mm
:
00
`; // 用来做同期对比,把日期拉到同一区间
let _maxValues = [];
/**
* 生成泳道图,分两种情况
* 1. 当最大值最小值都是正数时;
* 2. 当最大值小于零时(此时,最小值一定小于零);
*/
dataSource?.[0]?.dataModel.forEach((item) => {
const {firstPV, lastPV, maxPV, minPV, pt} = item;
_maxValues.push(maxPV);
let time = contrast ? moment(pt).format(formatStr) : pt;
_maxData.push([
moment(time).valueOf(),
(maxPV > 0 ? maxPV - minPV : minPV - maxPV).toFixed(2),
]);
_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'};
decorateAxisGridLine(xAxis, showGridLine);
let _unit = '';
series = series.map((item) => {
_unit = item.unit ?? '';
item.areaStyle = null;
return {...item, showSymbol: false};
});
[[..._minData], [..._maxData]].forEach((item, index) => {
series.push({
name: index === 0 ? '周期最小值' : '周期最大值',
type: 'line',
data: item,
lineStyle: {
opacity: 0,
},
...(index !== 0
? {
areaStyle: {
color: series?.[0]?.itemStyle?.color ?? '#65a0d1',
opacity: 0.2,
},
}
: {}),
stack: 'confidence-band',
symbol: 'none',
});
});
tooltip = {
trigger: 'axis',
formatter: (e) => {
return `
<
div
>
$
{
headTemplate
(
e
[
0
])}
$
{
headTemplate
(
e
[
0
])}
<
div
>
<
div
>
<
div
style
=
"display: flex; align-items: center;"
>
<
div
style
=
"display: flex; align-items: center;"
>
<
span
style
=
"${isMobile()
<
span
style
=
"${
? 'width: ' +
isMobile()
handlePx(90, 'px') +
? 'width: ' +
';overflow:hidden;text-overflow:ellipsis;white-space:nowrap'
handlePx(90, 'px') +
: ''
';overflow:hidden;text-overflow:ellipsis;white-space:nowrap'
}"
>
$
{
e
[
0
].
seriesName
: ''
}
<
/span><span style="display:inline-block;">:</
span
>
}"
>
$
{
e
[
0
].
seriesName
}
<
/span><span style="display:inline-block;">:</
span
>
<
span
style
=
"color: ${COLOR.NORMAL};margin: 0 ${handlePx(
<
span
style
=
"color: ${COLOR.NORMAL};margin: 0 ${handlePx(
5,
5,
'px',
'px',
)} 0 auto;"
>
$
{
e
[
0
]?.
value
?.[
1
]
??
'-'
}
<
/span
>
)} 0 auto;"
>
$
{
e
[
0
]?.
value
?.[
1
]
??
'-'
}
<
/span
>
<
span
style
=
"font-size: ${handlePx(12, 'px')};"
>
$
{
_unit
??
''
}
<
/span
>
<
span
style
=
"font-size: ${handlePx(12, 'px')};"
>
$
{
_unit
??
''
}
<
/span
>
<
/div
>
<
/div
>
<
div
style
=
"display: ${lineDataType === '特征曲线' ? 'flex' : 'none'
<
div
style
=
"display: ${
}; align-items: center;"
>
lineDataType === '特征曲线' ? 'flex' : 'none'
}; align-items: center;"
>
<
span
>
周期最小值
<
/span><span style="display:inline-block;">:</
span
>
<
span
>
周期最小值
<
/span><span style="display:inline-block;">:</
span
>
<
span
style
=
"color: ${COLOR.AVG};margin: 0 ${handlePx(
<
span
style
=
"color: ${COLOR.AVG};margin: 0 ${handlePx(
5,
5,
'px',
'px',
)} 0 auto;"
>
$
{
e
?.[
1
]?.
value
?.[
1
]
??
'-'
}
<
/span
>
)} 0 auto;"
>
$
{
e
?.[
1
]?.
value
?.[
1
]
??
'-'
}
<
/span
>
<
span
style
=
"font-size: ${handlePx(12, 'px')};"
>
$
{
_unit
??
''
}
<
/span
>
<
span
style
=
"font-size: ${handlePx(12, 'px')};"
>
$
{
_unit
??
''
}
<
/span
>
<
/div
>
<
/div
>
<
div
style
=
"display: ${lineDataType === '特征曲线' ? 'flex' : 'none'
<
div
style
=
"display: ${
}; align-items: center;"
>
lineDataType === '特征曲线' ? 'flex' : 'none'
}; align-items: center;"
>
<
span
>
周期最大值
<
/span><span style="display:inline-block;">:</
span
>
<
span
>
周期最大值
<
/span><span style="display:inline-block;">:</
span
>
<
span
style
=
"color: ${COLOR.AVG};margin: 0 ${handlePx(
<
span
style
=
"color: ${COLOR.AVG};margin: 0 ${handlePx(
5,
5,
'px',
'px',
)} 0 auto;"
>
$
{
_maxValues
[
e
?.[
2
]?.
dataIndex
]
??
'-'
}
<
/span
>
)} 0 auto;"
>
$
{
_maxValues
[
e
?.[
2
]?.
dataIndex
]
??
'-'
}
<
/span
>
<
span
style
=
"font-size: ${handlePx(12, 'px')};"
>
$
{
_unit
??
''
}
<
/span
>
<
span
style
=
"font-size: ${handlePx(12, 'px')};"
>
$
{
_unit
??
''
}
<
/span
>
<
/div
>
<
/div
>
<
/div
>
<
/div
>
<
/div>`
;
<
/div>`
;
},
},
};
};
}
// 单曲线需要标记最大值、最小值的情况下,需要增加自定义的series,将最大最小值显示在图表上
if
(
dataSource
?.[
0
]?.
dataModel
?.
length
&&
chartType
===
'lineChart'
)
{
let
_customSeries
=
returnCustomSeries
(
dataSource
);
series
.
push
(
_customSeries
);
}
}
else
{
tooltip
=
tooltipAccessor
(
series
.
map
((
item
)
=>
item
.
unit
),
{
contrastOption
,
contrast
},
);
}
}
tooltip
.
timeFormat
=
tooltipTimeFormat
;
// 单曲线需要标记最大值、最小值的情况下,需要增加自定义的series,将最大最小值显示在图表上
let
_legendData
=
series
if
(
dataSource
?.[
0
]?.
dataModel
?.
length
&&
chartType
===
'lineChart'
)
{
.
filter
((
item
)
=>
!
[
'周期最大值'
,
'周期最小值'
,
'自定义'
].
includes
(
item
.
name
))
// legend中,过滤掉辅助业务的legend
let
_customSeries
=
returnCustomSeries
(
dataSource
);
.
map
((
item
)
=>
item
.
name
);
series
.
push
(
_customSeries
);
assignOptions
(
restOption
,
xAxis
,
_legendData
,
chartType
,
contrast
,
contrastOption
,
config
);
}
let
_options
=
{
}
else
{
yAxis
,
tooltip
=
tooltipAccessor
(
grid
,
series
.
map
((
item
)
=>
item
.
unit
),
xAxis
,
{
contrastOption
,
contrast
},
series
,
);
tooltip
,
}
visualMap
,
tooltip
.
timeFormat
=
tooltipTimeFormat
;
...
restOption
,
let
_legendData
=
series
};
.
filter
((
item
)
=>
!
[
'周期最大值'
,
'周期最小值'
,
'自定义'
].
includes
(
item
.
name
))
// legend中,过滤掉辅助业务的legend
return
_options
;
.
map
((
item
)
=>
item
.
name
);
assignOptions
(
restOption
,
xAxis
,
_legendData
,
chartType
,
contrast
,
contrastOption
,
config
);
let
_options
=
{
yAxis
,
grid
,
xAxis
,
series
,
tooltip
,
visualMap
,
...
restOption
,
};
return
_options
;
};
};
export
default
optionGenerator
;
export
default
optionGenerator
;
const
handleDataSource
=
(
dataSource
)
=>
{
const
handleDataSource
=
(
dataSource
)
=>
{
let
_temp
=
null
;
let
_temp
=
null
;
let
_data
=
[];
let
_data
=
[];
let
_dataLength
=
dataSource
[
0
].
dataModel
.
length
;
let
_dataLength
=
dataSource
[
0
].
dataModel
.
length
;
// handleSpecial2()
// handleSpecial2()
dataSource
[
0
].
dataModel
.
forEach
((
item
,
index
)
=>
{
dataSource
[
0
].
dataModel
.
forEach
((
item
,
index
)
=>
{
if
(
index
===
0
)
{
if
(
index
===
0
)
{
_data
.
push
(
item
)
_data
.
push
(
item
);
}
else
if
(
index
===
_dataLength
-
1
)
{
}
else
if
(
index
===
_dataLength
-
1
)
{
_data
.
push
(
item
);
_data
.
push
(
item
);
}
else
{
}
else
{
if
(
_temp
.
pv
!==
item
.
pv
)
{
if
(
_temp
.
pv
!==
item
.
pv
)
{
_data
.
push
(
item
);
_data
.
push
(
item
);
}
}
}
}
_temp
=
item
;
_temp
=
item
;
});
});
return
_data
return
_data
;
};
};
const
returnLegend
=
(
sensorType
)
=>
{
const
returnLegend
=
(
sensorType
)
=>
{
const
_colorMap
=
{
const
_colorMap
=
{
变频
:
'#1685ff'
,
变频
:
'#1685ff'
,
工频
:
'#00d0c7'
,
工频
:
'#00d0c7'
,
运行
:
'#1685ff'
,
运行
:
'#1685ff'
,
故障
:
'#ff6b37'
,
故障
:
'#ff6b37'
,
停止
:
'#666666'
,
停止
:
'#666666'
,
};
};
};
};
const
handleSpecial2
=
(
special
,
sensorName
,
sensorType
,
data1
,
data2
)
=>
{
const
handleSpecial2
=
(
special
,
sensorName
,
sensorType
,
data1
,
data2
)
=>
{
let
color
=
''
;
let
color
=
''
;
let
name
=
''
;
let
name
=
''
;
let
value1
=
''
;
let
value1
=
''
;
let
value2
=
''
;
let
value2
=
''
;
// 1. valDesc
// 1. valDesc
if
(
sensorType
===
'状态值'
)
{
if
(
sensorType
===
'状态值'
)
{
const
_colorMap
=
{
const
_colorMap
=
{
变频
:
'#1685ff'
,
变频
:
'#1685ff'
,
工频
:
'#00d0c7'
,
工频
:
'#00d0c7'
,
运行
:
'#1685ff'
,
运行
:
'#1685ff'
,
故障
:
'#ff6b37'
,
故障
:
'#ff6b37'
,
停止
:
'#666666'
,
停止
:
'#666666'
,
};
};
let
_valDescMap
=
special
.
allValDesc
[
sensorName
]?.
split
(
';'
).
reduce
((
final
,
cur
)
=>
{
let
_valDescMap
=
special
.
allValDesc
[
sensorName
]?.
split
(
';'
).
reduce
((
final
,
cur
)
=>
{
let
_arr
=
cur
.
split
(
':'
);
let
_arr
=
cur
.
split
(
':'
);
final
[
_arr
[
0
]]
=
_arr
[
1
];
final
[
_arr
[
0
]]
=
_arr
[
1
];
return
final
return
final
;
},
{});
},
{});
name
=
_valDescMap
[
data1
.
pv
];
name
=
_valDescMap
[
data1
.
pv
];
color
=
_colorMap
[
name
];
color
=
_colorMap
[
name
];
}
}
//2. 开关量
//2. 开关量
if
(
sensorType
===
'开关值'
)
{
if
(
sensorType
===
'开关值'
)
{
const
_switchColorMap
=
{
const
_switchColorMap
=
{
0
:
'#666666'
,
0
:
'#666666'
,
1
:
'#1685ff'
1
:
'#1685ff'
,
};
};
const
_switchNameMap
=
{
const
_switchNameMap
=
{
0
:
'关'
,
0
:
'关'
,
1
:
'开'
1
:
'开'
,
}
};
name
=
_switchNameMap
[
data1
.
pv
];
name
=
_switchNameMap
[
data1
.
pv
];
color
=
_switchColorMap
[
data1
.
pv
];
color
=
_switchColorMap
[
data1
.
pv
];
}
}
value1
=
moment
(
data1
.
pt
).
valueOf
();
value1
=
moment
(
data1
.
pt
).
valueOf
();
value2
=
moment
(
data2
.
pt
).
valueOf
();
value2
=
moment
(
data2
.
pt
).
valueOf
();
return
{
color
,
value1
,
value2
,
name
}
return
{
color
,
value1
,
value2
,
name
};
};
};
const
handleDataToSeries
=
(
special
,
sensorName
,
sensorType
,
data
)
=>
{
const
handleDataToSeries
=
(
special
,
sensorName
,
sensorType
,
data
)
=>
{
let
_data
=
[];
let
_data
=
[];
let
_legend
=
[];
let
_legend
=
[];
data
.
forEach
((
item
,
index
)
=>
{
data
.
forEach
((
item
,
index
)
=>
{
if
(
index
===
data
.
length
-
1
)
return
;
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
(
if
(
!
_legend
.
includes
(
name
))
_legend
.
push
(
name
);
special
,
_data
.
push
({
sensorName
,
itemStyle
:
{
normal
:
{
color
}},
sensorType
,
name
:
name
,
item
,
value
:
[
0
,
value1
,
value2
,
`
${
item
.
pt
}
-
${
data
[
index
+
1
].
pt
}
`
]
data
[
index
+
1
],
});
);
if
(
!
_legend
.
includes
(
name
))
_legend
.
push
(
name
);
_data
.
push
({
itemStyle
:
{
normal
:
{
color
}
},
name
:
name
,
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
specialTypeChartOptionGenerator
=
({
const
{
special
,
sensorType
}
=
config
;
dataSource
,
const
{
allSensorType
,
allPointAddress
}
=
special
;
cusOption
,
// 处理原始数据,处理数据为后series数据
contrast
,
const
sensorName
=
dataSource
[
0
].
sensorName
;
contrastOption
,
let
_data
=
handleDataSource
(
dataSource
);
smooth
,
let
{
data
,
legend
}
=
handleDataToSeries
(
special
,
sensorName
,
sensorType
,
_data
);
config
,
// 1. x/y轴
})
=>
{
let
xAxis
=
{
const
{
special
,
sensorType
}
=
config
;
type
:
'time'
,
const
{
allSensorType
,
allPointAddress
}
=
special
;
axisLabel
:
{
// 处理原始数据,处理数据为后series数据
formatter
:
contrast
?
(
contrastOption
===
'month'
?
'{dd}日'
:
'{HH}:{mm}'
)
const
sensorName
=
dataSource
[
0
].
sensorName
;
:
{
let
_data
=
handleDataSource
(
dataSource
);
year
:
'{yyyy}'
,
let
{
data
,
legend
}
=
handleDataToSeries
(
special
,
sensorName
,
sensorType
,
_data
);
month
:
'{MMM}'
,
// 1. x/y轴
day
:
'{MMM}{d}日'
,
let
xAxis
=
{
hour
:
'{HH}:{mm}'
,
type
:
'time'
,
minute
:
'{HH}:{mm}'
,
axisLabel
:
{
second
:
'{HH}:{mm}:{ss}'
,
formatter
:
contrast
none
:
'{yyyy}-{MM}-{dd} {hh}:{mm}:{ss}'
,
?
contrastOption
===
'month'
},
?
'{dd}日'
},
:
'{HH}:{mm}'
minorTick
:
{
:
{
lineStyle
:
{
year
:
'{yyyy}'
,
color
:
"#e2e2e2"
month
:
'{MMM}'
,
},
day
:
'{MMM}{d}日'
,
show
:
true
,
hour
:
'{HH}:{mm}'
,
splitNumber
:
2
minute
:
'{HH}:{mm}'
,
},
second
:
'{HH}:{mm}:{ss}'
,
minorSplitLine
:
{
none
:
'{yyyy}-{MM}-{dd} {hh}:{mm}:{ss}'
,
lineStyle
:
{
},
color
:
"#e2e2e2"
,
},
type
:
"dashed"
minorTick
:
{
},
lineStyle
:
{
show
:
true
color
:
'#e2e2e2'
,
},
},
splitLine
:
{
show
:
true
,
show
:
true
splitNumber
:
2
,
},
},
minInterval
:
3600
*
1000
minorSplitLine
:
{
};
lineStyle
:
{
let
yAxis
=
{
color
:
'#e2e2e2'
,
data
:
[
dataSource
[
0
].
sensorName
],
type
:
'dashed'
,
axisLine
:
{
},
show
:
true
show
:
true
,
},
},
minorTick
:
{
splitLine
:
{
lineStyle
:
{
show
:
true
,
color
:
"#e2e2e2"
},
},
minInterval
:
3600
*
1000
,
show
:
true
,
};
splitNumber
:
2
let
yAxis
=
{
},
data
:
[
dataSource
[
0
].
sensorName
],
minorSplitLine
:
{
axisLine
:
{
lineStyle
:
{
show
:
true
,
color
:
"#e2e2e2"
,
},
type
:
"dashed"
minorTick
:
{
},
lineStyle
:
{
show
:
true
color
:
'#e2e2e2'
,
},
},
splitLine
:
{
show
:
true
,
show
:
true
splitNumber
:
2
,
},
},
};
minorSplitLine
:
{
//2. series
lineStyle
:
{
let
series
=
[
color
:
'#e2e2e2'
,
{
type
:
'dashed'
,
type
:
'custom'
,
},
renderItem
:
renderStatusItem
,
show
:
true
,
itemStyle
:
{
},
opacity
:
0.8
splitLine
:
{
},
show
:
true
,
encode
:
{
},
x
:
[
1
,
2
],
};
y
:
0
//2. series
},
let
series
=
[
data
{
},
type
:
'custom'
,
...
legend
.
map
(
item
=>
{
renderItem
:
renderStatusItem
,
let
_map
=
{
itemStyle
:
{
变频
:
'#1685ff'
,
opacity
:
0.8
,
工频
:
'#00d0c7'
,
},
运行
:
'#1685ff'
,
encode
:
{
故障
:
'#ff6b37'
,
x
:
[
1
,
2
],
停止
:
'#666666'
,
y
:
0
,
关
:
'#666666'
,
},
开
:
'#1685ff'
data
,
}
},
return
{
...
legend
.
map
((
item
)
=>
{
type
:
'custom'
,
let
_map
=
{
name
:
item
,
变频
:
'#1685ff'
,
color
:
_map
[
item
],
工频
:
'#00d0c7'
,
renderItem
:
()
=>
{
运行
:
'#1685ff'
,
}
故障
:
'#ff6b37'
,
}
停止
:
'#666666'
,
})
关
:
'#666666'
,
];
开
:
'#1685ff'
,
let
grid
=
{
};
top
:
80
,
return
{
left
:
30
,
type
:
'custom'
,
right
:
10
,
name
:
item
,
bottom
:
60
,
color
:
_map
[
item
],
containLabel
:
true
renderItem
:
()
=>
{},
};
};
let
legendConfig
=
{
}),
show
:
true
,
];
data
:
legend
,
let
grid
=
{
selectedMode
:
false
,
top
:
80
,
right
:
10
,
left
:
30
,
top
:
30
,
right
:
10
,
icon
:
'rect'
,
bottom
:
60
,
itemWidth
:
14
,
containLabel
:
true
,
itemHeight
:
8
,
};
itemGap
:
20
,
let
legendConfig
=
{
};
show
:
true
,
let
_option
=
{
data
:
legend
,
xAxis
,
selectedMode
:
false
,
yAxis
,
right
:
10
,
grid
,
top
:
30
,
series
,
icon
:
'rect'
,
legend
:
legendConfig
,
itemWidth
:
14
,
tooltip
:
{
itemHeight
:
8
,
trigger
:
'item'
,
itemGap
:
20
,
formatter
:
function
(
params
)
{
};
return
params
.
marker
+
params
.
name
+
': '
+
params
?.
value
?.[
3
];
let
_option
=
{
}
xAxis
,
},
yAxis
,
dataZoom
:
[
grid
,
{
series
,
type
:
'slider'
,
legend
:
legendConfig
,
filterMode
:
'weakFilter'
,
tooltip
:
{
showDataShadow
:
false
,
trigger
:
'item'
,
labelFormatter
:
''
formatter
:
function
(
params
)
{
},
return
params
.
marker
+
params
.
name
+
': '
+
params
?.
value
?.[
3
];
{
},
type
:
'inside'
,
},
filterMode
:
'weakFilter'
dataZoom
:
[
}
{
],
type
:
'slider'
,
}
filterMode
:
'weakFilter'
,
return
_option
;
showDataShadow
:
false
,
labelFormatter
:
''
,
},
{
type
:
'inside'
,
filterMode
:
'weakFilter'
,
},
],
};
return
_option
;
};
};
export
{
export
{
specialTypeChartOptionGenerator
};
specialTypeChartOptionGenerator
}
\ No newline at end of file
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