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
3f662052
Commit
3f662052
authored
Jul 19, 2023
by
陈龙
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: 完善移动端适配
parent
6a5da773
Show whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
368 additions
and
214 deletions
+368
-214
package.json
package.json
+2
-1
package.json
packages/extend-components/EC_HistoryView/package.json
+2
-1
EC_HistoryView.md
...es/extend-components/EC_HistoryView/src/EC_HistoryView.md
+5
-1
SingleChart.js
packages/extend-components/EC_HistoryView/src/SingleChart.js
+1
-1
index.js
packages/extend-components/EC_HistoryView/src/demos/index.js
+1
-3
mobile.js
...ages/extend-components/EC_HistoryView/src/demos/mobile.js
+29
-0
index.less
packages/extend-components/EC_HistoryView/src/index.less
+6
-0
mobile.js
packages/extend-components/EC_HistoryView/src/mobile.js
+65
-44
utils.js
packages/extend-components/EC_HistoryView/src/utils.js
+257
-163
No files found.
package.json
View file @
3f662052
...
@@ -146,6 +146,7 @@
...
@@ -146,6 +146,7 @@
},
},
"dependencies"
:
{
"dependencies"
:
{
"
@babel/plugin-proposal-private-methods
"
:
"^7.18.6"
,
"
@babel/plugin-proposal-private-methods
"
:
"^7.18.6"
,
"
@wisdom-components/VmsVideo
"
:
"1.1.13"
,
"
@wisdom-components/basictable
"
:
"^1.5.14"
,
"
@wisdom-components/basictable
"
:
"^1.5.14"
,
"
@wisdom-components/ec_historyview
"
:
"^1.4.3"
,
"
@wisdom-components/ec_historyview
"
:
"^1.4.3"
,
"
@wisdom-components/empty
"
:
"^1.3.9"
,
"
@wisdom-components/empty
"
:
"^1.3.9"
,
...
@@ -153,8 +154,8 @@
...
@@ -153,8 +154,8 @@
"
@wisdom-components/loadbox
"
:
"1.1.4"
,
"
@wisdom-components/loadbox
"
:
"1.1.4"
,
"
@wisdom-components/timerangepicker
"
:
"^1.3.4"
,
"
@wisdom-components/timerangepicker
"
:
"^1.3.4"
,
"
@wisdom-components/videoslidermodal
"
:
"1.1.2"
,
"
@wisdom-components/videoslidermodal
"
:
"1.1.2"
,
"
@wisdom-components/VmsVideo
"
:
"1.1.13"
,
"
@wisdom-utils/utils
"
:
"0.0.46"
,
"
@wisdom-utils/utils
"
:
"0.0.46"
,
"
antd-mobile
"
:
"5.10.4"
,
"
classnames
"
:
"^2.2.6"
,
"
classnames
"
:
"^2.2.6"
,
"
cross-spawn
"
:
"^7.0.3"
,
"
cross-spawn
"
:
"^7.0.3"
,
"
echarts
"
:
"^5.4.0"
,
"
echarts
"
:
"^5.4.0"
,
...
...
packages/extend-components/EC_HistoryView/package.json
View file @
3f662052
...
@@ -32,6 +32,7 @@
...
@@ -32,6 +32,7 @@
"test"
:
"echo
\"
Error: run tests from root
\"
&& exit 1"
"test"
:
"echo
\"
Error: run tests from root
\"
&& exit 1"
},
},
"dependencies"
:
{
"dependencies"
:
{
"@babel/runtime"
:
"^7.17.9"
"@babel/runtime"
:
"^7.17.9"
,
"antd-mobile"
:
"5.10.4"
}
}
}
}
packages/extend-components/EC_HistoryView/src/EC_HistoryView.md
View file @
3f662052
...
@@ -24,9 +24,13 @@ path: /
...
@@ -24,9 +24,13 @@ path: /
<code
src=
"./demos/index.js"
>
<code
src=
"./demos/index.js"
>
## 移动端
<code
src=
"./demos/mobile.js"
>
## 多图表
## 多图表
<code
src=
"./demos/GridDemo.js"
>
[
//
]:
#
(<code src="./demos/GridDemo.js">)
## API
## API
...
...
packages/extend-components/EC_HistoryView/src/SingleChart.js
View file @
3f662052
...
@@ -32,7 +32,7 @@ const SimgleChart = memo((props) => {
...
@@ -32,7 +32,7 @@ const SimgleChart = memo((props) => {
showBoxOption
,
showBoxOption
,
};
};
return
optionGenerator
(
dataSource
,
null
,
contrast
,
contrastOption
,
smooth
,
config
);
return
optionGenerator
(
dataSource
,
null
,
contrast
,
contrastOption
,
smooth
,
config
);
},
[
dataSource
,
smooth
,
curveCenter
]);
},
[
dataSource
,
smooth
,
curveCenter
,
chartType
]);
useEffect
(()
=>
{
useEffect
(()
=>
{
chartRef
.
current
?.
resize
?.();
chartRef
.
current
?.
resize
?.();
...
...
packages/extend-components/EC_HistoryView/src/demos/index.js
View file @
3f662052
...
@@ -13,6 +13,7 @@ const deviceParams = [
...
@@ -13,6 +13,7 @@ const deviceParams = [
// deviceCode: 'EGBF00000002',
// deviceCode: 'EGBF00000002',
// deviceCode: 'EGBF00000018',
// deviceCode: 'EGBF00000018',
deviceCode
:
'XMYL00000345'
,
deviceCode
:
'XMYL00000345'
,
// deviceCode: 'XMYL00000000',
// deviceCode: 'EGBF00000014',
// deviceCode: 'EGBF00000014',
// sensors: '今日供水量,今日用电量,1#水箱液位,是否在线',
// sensors: '今日供水量,今日用电量,1#水箱液位,是否在线',
sensors
:
'进水压力'
,
sensors
:
'进水压力'
,
...
@@ -32,9 +33,6 @@ const Demo = () => {
...
@@ -32,9 +33,6 @@ const Demo = () => {
<
div
style
=
{{
height
:
700
}}
>
<
div
style
=
{{
height
:
700
}}
>
<
HistoryView
deviceParams
=
{
deviceParams
}
defaultModel
=
"curve"
/>
<
HistoryView
deviceParams
=
{
deviceParams
}
defaultModel
=
"curve"
/>
<
/div
>
<
/div
>
<
div
style
=
{{
height
:
300
}}
>
<
MobileHistoryChart
deviceParams
=
{
deviceParams
}
chartType
=
{
'boxChart'
}
/
>
<
/div
>
<
/div
>
<
/div
>
);
);
...
...
packages/extend-components/EC_HistoryView/src/demos/mobile.js
0 → 100644
View file @
3f662052
import
React
from
'react'
;
import
{
MobileHistoryChart
}
from
"../mobile"
;
const
deviceParams
=
[
/* {
deviceCode: 'EGBF00000141',
sensors: '今日供水量,今日用电量',
deviceType: '二供泵房',
pointAddressID: 208,
}, */
{
deviceCode
:
'EGBF00000141'
,
sensors
:
'今日供水量'
,
deviceType
:
'二供泵房'
,
pointAddressID
:
208
,
},
];
const
Demo
=
()
=>
{
return
(
<
div
>
<
div
style
=
{{
height
:
400
}}
>
<
MobileHistoryChart
deviceParams
=
{
deviceParams
}
/
>
<
/div
>
<
/div
>
);
};
export
default
Demo
;
packages/extend-components/EC_HistoryView/src/index.less
View file @
3f662052
...
@@ -199,3 +199,9 @@
...
@@ -199,3 +199,9 @@
opacity: 1;
opacity: 1;
}
}
}
}
.@{history-view}-item {
display: flex;
align-items: center;
margin-bottom: 10px;
}
packages/extend-components/EC_HistoryView/src/mobile.js
View file @
3f662052
import
React
,
{
useEffect
,
useMemo
,
useState
,
useContext
}
from
'react'
;
import
React
,
{
useEffect
,
useMemo
,
useState
,
useContext
}
from
'react'
;
import
GridChart
from
"./GridChart"
;
import
{
ConfigProvider
}
from
"antd"
;
import
{
ConfigProvider
}
from
"antd"
;
import
{
Selector
,
Checkbox
,
Space
}
from
'antd-mobile/es'
;
import
moment
from
"moment"
;
import
moment
from
"moment"
;
import
{
getDeviceAlarmScheme
,
getHistoryInfo
}
from
"./apis"
;
import
{
getDeviceAlarmScheme
,
getHistoryInfo
}
from
"./apis"
;
import
SimgleChart
from
"./SingleChart"
;
import
SimgleChart
from
"./SingleChart"
;
import
{
handlePx
}
from
"./utils"
;
import
styles
from
'./index.less'
;
// deviceAlarmSchemes 用来获取对应的 方案的最大值/最小值 标记状态
const
DATE_FORMAT
=
'YYYY-MM-DD HH:mm:ss'
;
// dataSource 获取的报警信息
// deviceParams,
// defaultDate,
// {
// deviceCode: 'XMYL00000345',
// sensors: '进水压力',
// deviceType: '熊猫压力表',
// pointAddressID: 4,
// },
//{
// "isDilute": true, // 抽稀
// "zoom": "30",// 抽稀
// "unit": "min",// 抽稀
// "ignoreOutliers": false, // 滤波
// "dateFrom": "2023-07-09 16:38:32",
// "dateTo": "2023-07-10 16:38:32",
// "acrossTables": [
// {
// "deviceCode": "XMYL00000297",
// "sensors": "进水压力,是否在线",
// "deviceType": "熊猫压力表"
// }
// ],
// "isBoxPlots": true // 箱线图
// }
const
DATE_FORMAT
=
'YYYY-MM-DD'
;
const
MobileHistoryChart
=
(
const
MobileHistoryChart
=
(
{
{
date
=
{
date
=
{
dateFrom
:
moment
().
format
(
`
${
DATE_FORMAT
}
00:00:00
`
),
dateFrom
:
moment
().
subtract
(
1
,
'days'
).
format
(
`
${
DATE_FORMAT
}
`
),
dateTo
:
moment
().
format
(
`
${
DATE_FORMAT
}
23:59:59
`
)
dateTo
:
moment
().
format
(
`
${
DATE_FORMAT
}
`
)
},
// 默认当天
},
// 默认当天
deviceParams
=
[],
// 设备参数,必传
deviceParams
=
[],
// 设备参数,必传
chartType
=
'lineChart'
,
// lineChart boxChart
chartType
=
'lineChart'
,
// lineChart boxChart
ignoreOutliers
=
true
,
// 滤波
//
ignoreOutliers = true, // 滤波
isDilute
=
true
,
// 抽稀去重
isDilute
=
true
,
// 抽稀去重
needMarkLine
=
true
,
needMarkLine
=
true
,
showBoxOption
=
true
,
// 开启箱线图配置,默认开启
showBoxOption
=
true
,
// 开启箱线图配置,默认开启
chartGrid
=
true
,
// 开启网格
chartGrid
=
true
,
// 开启网格
...
rest
}
}
)
=>
{
)
=>
{
const
[
deviceAlarmSchemes
,
setDeviceAlarmSchemes
]
=
useState
(
null
);
const
[
deviceAlarmSchemes
,
setDeviceAlarmSchemes
]
=
useState
(
null
);
const
[
chartDataSource
,
setChartDataSource
]
=
useState
(
null
);
const
[
chartDataSource
,
setChartDataSource
]
=
useState
(
null
);
const
[
options
,
setOptions
]
=
useState
({
curveCenter
:
true
,
ignoreOutliers
:
true
});
const
checkBoxOptions
=
useMemo
(()
=>
{
return
Object
.
keys
(
options
).
reduce
((
final
,
cur
)
=>
{
if
(
options
[
cur
])
final
.
push
(
cur
);
return
final
},
[]);
},
[
options
]);
const
[
lineType
,
setLineType
]
=
useState
([
chartType
]);
const
{
getPrefixCls
}
=
useContext
(
ConfigProvider
.
ConfigContext
);
const
{
getPrefixCls
}
=
useContext
(
ConfigProvider
.
ConfigContext
);
const
prefixCls
=
getPrefixCls
(
'history-view'
);
const
prefixCls
=
getPrefixCls
(
'history-view'
);
const
isBoxPlots
=
const
isBoxPlots
=
...
@@ -87,7 +72,7 @@ const MobileHistoryChart = (
...
@@ -87,7 +72,7 @@ const MobileHistoryChart = (
let
_params
=
{
let
_params
=
{
...
date
,
...
date
,
isBoxPlots
,
isBoxPlots
,
ignoreOutliers
,
ignoreOutliers
:
options
.
ignoreOutliers
,
isDilute
,
isDilute
,
...
thinKey
,
...
thinKey
,
acrossTables
acrossTables
...
@@ -139,20 +124,57 @@ const MobileHistoryChart = (
...
@@ -139,20 +124,57 @@ const MobileHistoryChart = (
});
});
}
}
useEffect
(()
=>
{
useEffect
(()
=>
{
getDataSource
();
getScheme
();
getScheme
();
},
[])
},
[])
return
deviceAlarmSchemes
&&
chartDataSource
?
<
SimgleChart
useEffect
(()
=>
{
getDataSource
();
},
[
options
.
ignoreOutliers
])
return
deviceAlarmSchemes
&&
chartDataSource
?
<
div
style
=
{{}}
>
{
chartDataSource
.
length
===
1
?
<
div
className
=
{
styles
[
`
${
prefixCls
}
-item`
]}
>
<
span
style
=
{{
fontSize
:
handlePx
(
16
)}}
>
曲线形态:
<
/span
>
<
Selector
options
=
{[
{
label
:
'线形图'
,
value
:
'lineChart'
},
{
label
:
'箱线图'
,
value
:
'boxChart'
}
]}
defaultValue
=
{
lineType
}
onChange
=
{(
arr
,
extend
)
=>
setLineType
(
arr
)}
/
>
<
/div> : '
'
}
<
div
className
=
{
styles
[
`
${
prefixCls
}
-item`
]}
>
<
span
style
=
{{
fontSize
:
handlePx
(
16
)}}
>
曲线设置:
<
/span
>
<
Checkbox
.
Group
value
=
{
checkBoxOptions
}
onChange
=
{
val
=>
{
let
_arr
=
Object
.
keys
(
options
);
let
_options
=
_arr
.
reduce
((
final
,
cur
)
=>
{
final
[
cur
]
=
!!
val
.
includes
(
cur
);
return
final
;
},
{})
setOptions
(
_options
);
}}
>
<
Space
direction
=
'horizontal'
>
<
Checkbox
value
=
'curveCenter'
>
曲线居中
<
/Checkbox
>
<
Checkbox
value
=
'ignoreOutliers'
>
滤波
<
/Checkbox
>
<
/Space
>
<
/Checkbox.Group
>
<
/div
>
<
div
style
=
{{
height
:
rest
.
height
||
'10rem'
,
width
:
rest
.
width
||
'100%'
}}
>
<
SimgleChart
showBoxOption
=
{
showBoxOption
}
showBoxOption
=
{
showBoxOption
}
curveCenter
=
{
true
}
curveCenter
=
{
options
.
curveCenter
}
chartGrid
=
{
chartGrid
}
showGridLine
=
{
chartGrid
}
prefixCls
=
{
prefixCls
}
prefixCls
=
{
prefixCls
}
dataSource
=
{
chartDataSource
}
dataSource
=
{
chartDataSource
}
chartType
=
{
isBoxPlots
?
chartType
:
null
}
chartType
=
{
isBoxPlots
?
lineType
[
0
]
:
null
}
deviceAlarmSchemes
=
{
deviceAlarmSchemes
}
deviceAlarmSchemes
=
{
deviceAlarmSchemes
}
/> : nul
l
/
>
<
/div
>
<
/div> : nul
l
}
}
export
{
export
{
MobileHistoryChart
MobileHistoryChart
}
}
\ No newline at end of file
packages/extend-components/EC_HistoryView/src/utils.js
View file @
3f662052
...
@@ -2,7 +2,7 @@ import moment from 'moment';
...
@@ -2,7 +2,7 @@ import moment from 'moment';
import
_
,
{
isArray
}
from
'lodash'
;
import
_
,
{
isArray
}
from
'lodash'
;
/** 轴宽度, 用于计算多轴显示时, 轴线偏移和绘图区域尺寸 */
/** 轴宽度, 用于计算多轴显示时, 轴线偏移和绘图区域尺寸 */
const
axisWidth
=
40
;
const
AXIS_WIDTH
=
40
;
const
COLOR
=
{
const
COLOR
=
{
NORMAL
:
'#1685FF'
,
NORMAL
:
'#1685FF'
,
UPER
:
'#fa8c16'
,
UPER
:
'#fa8c16'
,
...
@@ -13,6 +13,7 @@ const COLOR = {
...
@@ -13,6 +13,7 @@ const COLOR = {
LOWLOWER
:
'#FF0000'
,
LOWLOWER
:
'#FF0000'
,
AVG
:
'#00B8B1'
,
AVG
:
'#00B8B1'
,
};
};
const
isMobile
=
()
=>
{
const
isMobile
=
()
=>
{
const
userAgent
=
navigator
.
userAgent
.
toLowerCase
();
const
userAgent
=
navigator
.
userAgent
.
toLowerCase
();
if
(
if
(
...
@@ -23,7 +24,42 @@ const isMobile = () => {
...
@@ -23,7 +24,42 @@ const isMobile = () => {
return
true
;
return
true
;
}
}
return
false
;
return
false
;
};
const
returnRem
=
(
num
,
base
=
375
)
=>
num
*
(
base
/
375
);
export
const
handlePx
=
(
num
,
unit
=
''
)
=>
{
const
_isMobile
=
isMobile
();
const
_base
=
document
.
body
.
clientWidth
;
let
_num
=
_isMobile
?
`
${
returnRem
(
num
,
_base
)}
`
:
`
${
num
}
`
;
return
unit
?
`
${
_num
}${
unit
}
`
:
Number
(
_num
);
};
const
PC_OPTION
=
{
markPoint
:
{
padding
:
[
2
,
12
],
lineHeight
:
22
,
backgroundColor
:
window
.
globalConfig
&&
window
.
globalConfig
&&
window
.
globalConfig
.
variableTheme
?.
primaryColor
?
window
.
globalConfig
.
variableTheme
.
primaryColor
:
'#0087F7'
,
borderWidth
:
1
},
fontSize
:
16
,
fontColor
:
"#ffffff"
,
dataZoomHeight
:
28
}
}
const
MOBILE_OPTION
=
{
markPoint
:
{
padding
:
[
2
,
6
],
lineHeight
:
18
,
backgroundColor
:
'rgba(255,255,255,0.6)'
,
borderWidth
:
0
},
fontSize
:
handlePx
(
12
),
fontColor
:
"#0087F7"
,
dataZoomHeight
:
20
}
const
currentOption
=
isMobile
()
?
MOBILE_OPTION
:
PC_OPTION
;
/**
/**
* 图表系列名称格式化
* 图表系列名称格式化
*
*
...
@@ -149,6 +185,7 @@ export const alarmMarkLine = (dataItem, index, dataSource, schemes) => {
...
@@ -149,6 +185,7 @@ export const alarmMarkLine = (dataItem, index, dataSource, schemes) => {
};
};
export
const
minMaxMarkPoint
=
(
dataItem
,
index
,
dataSource
)
=>
{
export
const
minMaxMarkPoint
=
(
dataItem
,
index
,
dataSource
)
=>
{
const
_isMobile
=
isMobile
();
// 只有一个数据曲线时显示markline
// 只有一个数据曲线时显示markline
if
(
!
dataItem
||
dataSource
.
length
!==
1
)
return
{};
if
(
!
dataItem
||
dataSource
.
length
!==
1
)
return
{};
const
data
=
[];
const
data
=
[];
...
@@ -159,26 +196,18 @@ export const minMaxMarkPoint = (dataItem, index, dataSource) => {
...
@@ -159,26 +196,18 @@ export const minMaxMarkPoint = (dataItem, index, dataSource) => {
symbolOffset
:
[
0
,
'50%'
],
symbolOffset
:
[
0
,
'50%'
],
label
:
{
label
:
{
formatter
:
'{b|{b} }{c|{c}}'
,
formatter
:
'{b|{b} }{c|{c}}'
,
backgroundColor
:
...
currentOption
[
"markPoint"
],
window
.
globalConfig
&&
window
.
globalConfig
&&
window
.
globalConfig
.
variableTheme
?.
primaryColor
?
window
.
globalConfig
.
variableTheme
.
primaryColor
:
'#0087F7'
,
borderColor
:
'#ccc'
,
borderColor
:
'#ccc'
,
borderWidth
:
1
,
borderRadius
:
4
,
borderRadius
:
4
,
padding
:
[
2
,
10
],
lineHeight
:
22
,
position
:
'top'
,
position
:
'top'
,
distance
:
10
,
distance
:
10
,
rich
:
{
rich
:
{
b
:
{
b
:
{
color
:
'#fff'
,
color
:
currentOption
[
'fontColor'
]
,
},
},
c
:
{
c
:
{
color
:
'#fff'
,
color
:
currentOption
[
'fontColor'
]
,
fontSize
:
16
,
fontSize
:
currentOption
[
"fontSize"
]
,
fontWeight
:
700
,
fontWeight
:
700
,
},
},
},
},
...
@@ -252,99 +281,15 @@ export const offlineArea = (dataItem) => {
...
@@ -252,99 +281,15 @@ export const offlineArea = (dataItem) => {
data
:
datas
,
data
:
datas
,
};
};
};
};
const
headTemplate
=
(
param
)
=>
{
/**
* 图表配置项生成
*
* @param {any} dataSource 数据源
* @param {any} cusOption 自定义属性
* @param {any} contrast 是否为同期对比
* @param {any} contrastOption 同期对比周期配置, day|month
* @param {any} smooth Ture/false, 曲线/折线
* @param {any} config 额外配置信息
*/
const
optionGenerator
=
(
dataSource
,
cusOption
,
contrast
,
contrastOption
,
smooth
,
config
)
=>
{
const
needUnit
=
_
.
get
(
config
,
'needUnit'
,
false
);
const
curveCenter
=
_
.
get
(
config
,
'curveCenter'
,
false
);
const
nameWithSensor
=
_
.
get
(
config
,
'nameWithSensor'
,
true
);
const
showGridLine
=
_
.
get
(
config
,
'showGridLine'
,
true
);
const
showMarkLine
=
_
.
get
(
config
,
'showMarkLine'
,
false
);
const
showPoint
=
_
.
get
(
config
,
'showPoint'
,
false
);
const
deviceAlarmSchemes
=
_
.
get
(
config
,
'deviceAlarmSchemes'
,
[]);
const
chartType
=
_
.
get
(
config
,
'chartType'
,
null
);
// const justLine = _.get(config, 'justLine', false);
const
showBoxOption
=
_
.
get
(
config
,
'showBoxOption'
,
false
);
// 自定义属性
const
restOption
=
_
.
pick
(
cusOption
,
[
'title'
,
'legend'
]);
// 一种指标一个y轴
const
yAxisMap
=
new
Map
();
dataSource
.
forEach
((
item
,
index
)
=>
{
const
{
sensorName
,
unit
}
=
item
;
const
key
=
sensorName
;
if
(
!
yAxisMap
.
has
(
key
))
{
const
i
=
yAxisMap
.
size
;
const
axis
=
{
type
:
'value'
,
name
:
needUnit
?
unit
:
null
,
position
:
i
%
2
===
0
?
'left'
:
'right'
,
offset
:
Math
.
floor
(
i
/
2
)
*
axisWidth
,
axisLabel
:
{
formatter
:
(
value
)
=>
(
value
>
100000
?
`
${
value
/
1000
}
k`
:
value
),
},
axisLine
:
{
show
:
true
,
},
nameTextStyle
:
{
align
:
i
%
2
===
0
?
'right'
:
'left'
,
},
minorTick
:
{
lineStyle
:
{
color
:
'#e2e2e2'
,
},
},
minorSplitLine
:
{
lineStyle
:
{
color
:
'#e2e2e2'
,
type
:
'dashed'
,
},
},
};
yAxisMap
.
set
(
key
,
axis
);
}
// 曲线居中
if
(
curveCenter
&&
item
.
dataModel
&&
item
.
dataModel
.
length
>
0
)
{
const
[
min
,
max
]
=
minMax
(
item
);
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
yAxis
=
yAxisMap
.
size
>
0
?
[...
yAxisMap
.
values
()]
:
{
type
:
'value'
};
// 根据y轴个数调整边距
const
leftNum
=
Math
.
ceil
(
yAxisMap
.
size
/
2
);
const
rightNum
=
Math
.
floor
(
yAxisMap
.
size
/
2
);
const
grid
=
{
top
:
needUnit
?
80
:
60
,
left
:
10
+
leftNum
*
axisWidth
,
right
:
rightNum
===
0
?
20
:
rightNum
*
axisWidth
,
bottom
:
60
,
};
const
headTemplate
=
(
param
)
=>
{
if
(
!
param
)
return
''
;
if
(
!
param
)
return
''
;
const
{
name
,
axisValueLabel
,
axisType
,
axisValue
}
=
param
;
const
{
name
,
axisValueLabel
,
axisType
,
axisValue
}
=
param
;
const
timeFormat
=
'YYYY-MM-DD HH:mm:ss'
;
const
timeFormat
=
'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: 5px; padding-bottom: 5px
;">
${
text
}
</div>`
;
return
`<div style="border-bottom: 1px solid #F0F0F0; color: #808080; margin-bottom:
${
handlePx
(
5
,
'px'
)}
; padding-bottom:
${
handlePx
(
5
,
'px'
)}
;">
${
text
}
</div>`
;
};
};
const
seriesTemplate
=
(
param
,
unit
)
=>
{
const
seriesTemplate
=
(
param
,
unit
)
=>
{
if
(
!
param
)
return
''
;
if
(
!
param
)
return
''
;
const
{
value
,
encode
}
=
param
;
const
{
value
,
encode
}
=
param
;
// const val = value[encode.y[0]];
// const val = value[encode.y[0]];
...
@@ -352,40 +297,41 @@ const optionGenerator = (dataSource, cusOption, contrast, contrastOption, smooth
...
@@ -352,40 +297,41 @@ const optionGenerator = (dataSource, cusOption, contrast, contrastOption, smooth
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>
${
isMobile
()
?
'实际值'
:
param
.
seriesName
}
</span><span style="display:inline-block;">:</span>
<span style="
${
isMobile
()
?
'width: '
+
handlePx
(
90
,
'px'
)
+
';overflow:hidden;text-overflow:ellipsis;white-space:nowrap'
:
''
}
">
${
param
.
seriesName
}
</span>
<span style="color:
${
color
}
;margin: 0 5px 0 auto;">
${
value
?.
toFixed
(
3
)
??
'-'
}
<
/span
>
<span style="display:inline-block;">:</span>
<
span
style
=
"font-size: 12px;"
>
$
{
_unit
}
<
/span
>
<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>`
;
<
/div>`
;
return
param
.
componentSubType
!==
'candlestick'
return
param
.
componentSubType
!==
'candlestick'
?
`<div style="display: flex; align-items: center;">
?
`<div style="display: flex; align-items: center;">
<span
>
${
isMobile
()
?
'实际值'
:
param
.
seriesName
}
</span><span style="display:inline-block;">:</span>
<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
5px
0 auto;">
${
value
[
1
]
??
'-'
}
<
/span
>
<span style="color:
${
COLOR
.
AVG
}
;margin: 0
${
handlePx
(
5
,
'px'
)}
0 auto;">
${
value
[
1
]
??
'-'
}
<
/span
>
<
span
style
=
"font-size:
12px
;"
>
$
{
_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
5px
0 auto;">
${
value
[
1
]
??
'-'
}
<
/span
>
<span style="color:
${
COLOR
.
AVG
}
;margin: 0
${
handlePx
(
5
,
'px'
)}
0 auto;">
${
value
[
1
]
??
'-'
}
<
/span
>
<
span
style
=
"font-size:
12px
;"
>
$
{
_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
5px
0 auto;"
>
$
{
value
[
2
]
??
'-'
}
<
/span
>
<
span
style
=
"color: ${COLOR.AVG};margin: 0
${handlePx(5, 'px')}
0 auto;"
>
$
{
value
[
2
]
??
'-'
}
<
/span
>
<
span
style
=
"font-size:
12px
;"
>
$
{
_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
5px
0 auto;"
>
$
{
value
[
3
]
??
'-'
}
<
/span
>
<
span
style
=
"color: ${COLOR.AVG};margin: 0
${handlePx(5, 'px')}
0 auto;"
>
$
{
value
[
3
]
??
'-'
}
<
/span
>
<
span
style
=
"font-size:
12px
;"
>
$
{
_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
5px
0 auto;"
>
$
{
value
[
4
]
??
'-'
}
<
/span
>
<
span
style
=
"color: ${COLOR.AVG};margin: 0
${handlePx(5, 'px')}
0 auto;"
>
$
{
value
[
4
]
??
'-'
}
<
/span
>
<
span
style
=
"font-size:
12px
;"
>
$
{
_unit
}
<
/span
>
<
span
style
=
"font-size:
${handlePx(12, 'px')}
;"
>
$
{
_unit
}
<
/span
>
<
/div
>
<
/div
>
`;
`;
};
};
const tooltipAccessor = (unit) => {
const tooltipAccessor = (unit) => {
return {
return {
formatter: function (params, ticket, callback) {
formatter: function (params, ticket, callback) {
let tooltipHeader = '';
let tooltipHeader = '';
...
@@ -407,7 +353,18 @@ const optionGenerator = (dataSource, cusOption, contrast, contrastOption, smooth
...
@@ -407,7 +353,18 @@ const optionGenerator = (dataSource, cusOption, contrast, contrastOption, smooth
`;
`;
},
},
};
};
};
};
const returnXAxis = ({
dataSource,
contrast,
contrastOption,
nameWithSensor,
showMarkLine,
deviceAlarmSchemes,
showPoint,
restOption,
smooth
}) => {
// 根据"指标名称"分类yAxis
// 根据"指标名称"分类yAxis
const yAxisInterator = (() => {
const yAxisInterator = (() => {
const map = new Map();
const map = new Map();
...
@@ -475,21 +432,177 @@ const optionGenerator = (dataSource, cusOption, contrast, contrastOption, smooth
...
@@ -475,21 +432,177 @@ const optionGenerator = (dataSource, cusOption, contrast, contrastOption, smooth
.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),
);
);
let xAxis = {type: 'time', min, max};
return {xAxis: {type: 'time', min, max}, series};
}
const handleDefault = (config, cusOption) => {
const needUnit = _.get(config, 'needUnit', false);
const curveCenter = _.get(config, 'curveCenter', false);
const nameWithSensor = _.get(config, 'nameWithSensor', true);
const showGridLine = _.get(config, 'showGridLine', true);
const showMarkLine = _.get(config, 'showMarkLine', false);
const showPoint = _.get(config, 'showPoint', false);
const deviceAlarmSchemes = _.get(config, 'deviceAlarmSchemes', []);
const chartType = _.get(config, 'chartType', null);
// const justLine = _.get(config, 'justLine', false);
const showBoxOption = _.get(config, 'showBoxOption', false);
// 自定义属性
const restOption = _.pick(cusOption, ['title', 'legend']);
return {
needUnit,
curveCenter,
nameWithSensor,
showGridLine,
showMarkLine,
showPoint,
deviceAlarmSchemes,
chartType,
showBoxOption,
restOption
}
}
const handleYAxis = ({dataSource, needUnit, curveCenter, showGridLine}) => {
// 一种指标一个y轴
const yAxisMap = new Map();
dataSource.forEach((item, index) => {
const {sensorName, unit} = item;
const key = sensorName;
if (!yAxisMap.has(key)) {
const i = yAxisMap.size;
const axis = {
type: 'value',
name: needUnit ? unit : null,
position: i % 2 === 0 ? 'left' : 'right',
offset: Math.floor(i / 2) * AXIS_WIDTH,
axisLabel: {
formatter: (value) => (value > 100000 ? `
$
{
value
/
1000
}
k
` : value),
},
axisLine: {
show: true,
},
nameTextStyle: {
align: i % 2 === 0 ? 'right' : 'left',
},
minorTick: {
lineStyle: {
color: '#e2e2e2',
},
},
minorSplitLine: {
lineStyle: {
color: '#e2e2e2',
type: 'dashed',
},
},
};
yAxisMap.set(key, axis);
}
// 曲线居中
if (curveCenter && item.dataModel && item.dataModel.length > 0) {
const [min, max] = minMax(item);
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 yAxis = yAxisMap.size > 0 ? [...yAxisMap.values()] : {type: 'value'};
// 根据y轴个数调整边距
const leftNum = Math.ceil(yAxisMap.size / 2);
const rightNum = Math.floor(yAxisMap.size / 2);
return {leftNum, rightNum, yAxis};
}
const assignOptions = (restOption, xAxis, legendData) => {
restOption.dataZoom = [
{
show: true,
bottom: 10,
start: 0,
end: 100,
height: currentOption['dataZoomHeight'],
type: 'inside',
zoomOnMouseWheel: true,
},
{
show: true,
bottom: 10,
start: 0,
end: 100,
height: currentOption['dataZoomHeight'],
type: 'slider',
zoomOnMouseWheel: true,
},
];
xAxis.minInterval = 3600 * (1 * 1000);
if (legendData) {
restOption.legend = {
// orient: 'vertical',
data: legendData,
itemGap: 10,
padding: [0, 0, 0, 200],
textStyle: {
width: 120,
overflow: 'truncate',
},
}
}
};
/**
* 图表配置项生成
*
* @param {any} dataSource 数据源
* @param {any} cusOption 自定义属性
* @param {any} contrast 是否为同期对比
* @param {any} contrastOption 同期对比周期配置, day|month
* @param {any} smooth Ture/false, 曲线/折线
* @param {any} config 额外配置信息
*/
const optionGenerator = (dataSource, cusOption, contrast, contrastOption, smooth, config) => {
const {
needUnit,
curveCenter,
nameWithSensor,
showGridLine,
showMarkLine,
showPoint,
deviceAlarmSchemes,
chartType,
showBoxOption,
restOption
} = handleDefault(config, cusOption);
const {leftNum, rightNum, yAxis} = handleYAxis({dataSource, needUnit, curveCenter, showGridLine});
const grid = {
top: needUnit ? 80 : 60,
// top: 200,
left: 10 + leftNum * AXIS_WIDTH,
right: rightNum === 0 ? 20 : rightNum * AXIS_WIDTH,
bottom: 60,
};
let {xAxis, series} = returnXAxis({
dataSource,
contrast,
contrastOption,
nameWithSensor,
showMarkLine,
deviceAlarmSchemes,
showPoint,
smooth,
restOption
});
decorateAxisGridLine(xAxis, showGridLine);
decorateAxisGridLine(xAxis, showGridLine);
const tooltipTimeFormat = !contrast
const tooltipTimeFormat = !contrast
? 'YYYY-MM-DD HH:mm:ss'
? 'YYYY-MM-DD HH:mm:ss'
: contrastOption === 'day'
: contrastOption === 'day'
? 'HH:mm'
? 'HH:mm'
: 'DD HH:mm';
: 'DD HH:mm';
let tooltip = {
let tooltip = {};
timeFormat: tooltipTimeFormat,
// 增加箱线图的逻辑,单曲线才存在该逻辑
// trigger: 'axis',
// axisPointer: {
// type: 'cross'
// }
};
// 增加箱线图的逻辑,单曲线才存在
if (chartType && showBoxOption) {
if (chartType && showBoxOption) {
if (chartType === 'boxChart') {
if (chartType === 'boxChart') {
const otherData =
const otherData =
...
@@ -497,17 +610,12 @@ const optionGenerator = (dataSource, cusOption, contrast, contrastOption, smooth
...
@@ -497,17 +610,12 @@ const optionGenerator = (dataSource, cusOption, contrast, contrastOption, smooth
const {firstPV, lastPV, maxPV, minPV, pt} = item;
const {firstPV, lastPV, maxPV, minPV, pt} = item;
return [moment(pt).valueOf(), firstPV, lastPV, minPV, maxPV];
return [moment(pt).valueOf(), firstPV, lastPV, minPV, maxPV];
}) || []; //当存在othersData的时候,只是单曲线
}) || []; //当存在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);
decorateAxisGridLine(xAxis, showGridLine);
let unit = '';
let unit = '';
series = series.map((item) => {
series = series.map((item) => {
if (item.unit) unit = item.unit;
if (item.unit) unit = item.unit;
let _item = {...item, symbol: 'none'};
return {...item, symbol: 'none'};
/* _item.data = _item?.data?.map(d => {
return d[1] || null
}) || [];*/
return _item;
});
});
series.push({
series.push({
type: 'candlestick',
type: 'candlestick',
...
@@ -522,7 +630,8 @@ const optionGenerator = (dataSource, cusOption, contrast, contrastOption, smooth
...
@@ -522,7 +630,8 @@ const optionGenerator = (dataSource, cusOption, contrast, contrastOption, smooth
},
},
});
});
tooltip = tooltipAccessor(unit);
tooltip = tooltipAccessor(unit);
} else {
}
if (chartType === 'lineChart') {
let _maxData = [];
let _maxData = [];
let _minData = [];
let _minData = [];
let _currentYear = moment().format('YYYY');
let _currentYear = moment().format('YYYY');
...
@@ -572,55 +681,40 @@ const optionGenerator = (dataSource, cusOption, contrast, contrastOption, smooth
...
@@ -572,55 +681,40 @@ const optionGenerator = (dataSource, cusOption, contrast, contrastOption, smooth
$
{
headTemplate
(
e
[
0
])}
$
{
headTemplate
(
e
[
0
])}
<
div
>
<
div
>
<
div
style
=
"display: flex; align-items: center;"
>
<
div
style
=
"display: flex; align-items: center;"
>
<
span
>
$
{
<
span
style
=
"${isMobile() ? 'width: ' + handlePx(90, 'px') + ';overflow:hidden;text-overflow:ellipsis;white-space:nowrap' : ''}"
>
$
{
isMobile
()
?
'当前值'
:
e
[
0
].
seriesName
e
[
0
].
seriesName
}
<
/span><span style="display:inline-block;">:</
span
>
}
<
/span><span style="display:inline-block;">:</
span
>
<
span
style
=
"color: ${COLOR.NORMAL};margin: 0
5px
0 auto;"
>
$
{
<
span
style
=
"color: ${COLOR.NORMAL};margin: 0
${handlePx(5, 'px')}
0 auto;"
>
$
{
e
[
0
]?.
value
?.[
1
]
??
'-'
e
[
0
]?.
value
?.[
1
]
??
'-'
}
<
/span
>
}
<
/span
>
<
span
style
=
"font-size:
12px
;"
>
$
{
_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
5px
0 auto;"
>
$
{
<
span
style
=
"color: ${COLOR.AVG};margin: 0
${handlePx(5, 'px')}
0 auto;"
>
$
{
e
[
1
]?.
value
?.[
1
]
??
'-'
e
[
1
]?.
value
?.[
1
]
??
'-'
}
<
/span
>
}
<
/span
>
<
span
style
=
"font-size:
12px
;"
>
$
{
_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
5px
0 auto;"
>
$
{
<
span
style
=
"color: ${COLOR.AVG};margin: 0
${handlePx(5, 'px')}
0 auto;"
>
$
{
_maxValues
[
e
[
2
].
dataIndex
]
??
'-'
_maxValues
[
e
[
2
].
dataIndex
]
??
'-'
}
<
/span
>
}
<
/span
>
<
span
style
=
"font-size:
12px
;"
>
$
{
_unit
}
<
/span
>
<
span
style
=
"font-size:
${handlePx(12, 'px')}
;"
>
$
{
_unit
}
<
/span
>
<
/div
>
<
/div
>
<
/div
>
<
/div
>
<
/div>`
;
<
/div>`
;
},
},
};
};
}
}
}
else
{
tooltip
=
tooltipAccessor
();
}
}
restOption
.
dataZoom
=
[
tooltip
.
timeFormat
=
tooltipTimeFormat
;
{
let
_legendData
=
series
.
filter
(
item
=>
!
[
'最大值'
,
'最小值'
].
includes
(
item
.
name
)).
map
(
item
=>
item
.
name
);
show
:
true
,
assignOptions
(
restOption
,
xAxis
,
_legendData
);
bottom
:
10
,
debugger
start
:
0
,
end
:
100
,
height
:
28
,
type
:
'inside'
,
zoomOnMouseWheel
:
true
,
},
{
show
:
true
,
bottom
:
10
,
start
:
0
,
end
:
100
,
height
:
28
,
type
:
'slider'
,
zoomOnMouseWheel
:
true
,
},
];
xAxis
.
minInterval
=
3600
*
1
*
1000
;
return
{
return
{
yAxis
,
yAxis
,
grid
,
grid
,
...
...
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