|
|
@ -1,4 +1,5 @@ |
|
|
|
import React, { useEffect, useRef, useState } from 'react'; |
|
|
|
import { Skeleton, Button, Pagination, Select, Popconfirm, Table, Tooltip } from '@douyinfe/semi-ui'; |
|
|
|
import { connect } from 'react-redux'; |
|
|
|
import Header from '../components/header'; |
|
|
|
import Body from '../components/body' |
|
|
@ -6,18 +7,180 @@ import Card from '../components/card' |
|
|
|
import '../style.less' |
|
|
|
import ReactECharts from 'echarts-for-react'; |
|
|
|
import moment from 'moment' |
|
|
|
import PerfectScrollbar from "perfect-scrollbar"; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let interrupt |
|
|
|
let repair |
|
|
|
let overviewScrollbar; |
|
|
|
const Bigscreen = ({ dispatch, actions, user, match, history, clientHeight, groupStatisticOnline }) => { |
|
|
|
|
|
|
|
const [InterruptRank, setInterruptRank] = useState([]) |
|
|
|
const [online, setOnline] = useState([]) |
|
|
|
const [value, setValue] = useState([]) |
|
|
|
const [time, setTime] = useState([]) |
|
|
|
const [groupProject, setGroupProject] = useState([]) |
|
|
|
const [proportion, setProportion] = useState([]) |
|
|
|
const [formatter, setFormatter] = useState({}) |
|
|
|
|
|
|
|
|
|
|
|
const [alarmData, setAlarmData] = useState()//第三项之后的数据 |
|
|
|
const [biggest, setBiggest] = useState()//最大的刻度值 |
|
|
|
const [mockData, setMockData] = useState()//所有的告警数据 |
|
|
|
const [xData, setXData] = useState([])//横坐标 |
|
|
|
const self = useRef({ myChart: null }); |
|
|
|
|
|
|
|
|
|
|
|
useEffect(() => { |
|
|
|
let groupId = JSON.parse(localStorage.getItem('project_group'))?.find(v => user?.id == v.userId)?.projectGroupId |
|
|
|
console.log(); |
|
|
|
dispatch(actions.projectGroup.groupStatisticOnline({ groupId })) |
|
|
|
statisticOnline(groupId) |
|
|
|
//计算当前时间,定时更新 |
|
|
|
timeRequest(groupId) |
|
|
|
dispatch(actions.projectGroup.groupStatisticAlarm({ groupId })).then(res => { |
|
|
|
if (res.success) { |
|
|
|
setMockData(res.payload.data) |
|
|
|
} |
|
|
|
}) |
|
|
|
|
|
|
|
|
|
|
|
dispatch(actions.projectGroup.groupProject({ groupId })).then(res => { |
|
|
|
if (res.success) { |
|
|
|
setGroupProject(res.payload.data?.map(v => ({ ...v, value: (Math.random() * 20).toFixed(0) })) || []) |
|
|
|
setProportion([...res.payload.data?.slice(0, 3)?.map(v => ({ name: v.name || v.pepProjectName, value: (Math.random() * 20).toFixed(0) })), { value: 20, name: '其它' }]) |
|
|
|
} |
|
|
|
}) |
|
|
|
|
|
|
|
|
|
|
|
const interruptDom = document.getElementById("interrupt"); |
|
|
|
if (interruptDom) { |
|
|
|
interrupt = new PerfectScrollbar("#interrupt", { |
|
|
|
suppressScrollX: true, |
|
|
|
}); |
|
|
|
} |
|
|
|
const repairDom = document.getElementById("repair"); |
|
|
|
if (repairDom) { |
|
|
|
repair = new PerfectScrollbar("#repair", { |
|
|
|
suppressScrollX: true, |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
}, []) |
|
|
|
|
|
|
|
console.log(groupStatisticOnline); |
|
|
|
useEffect(() => { |
|
|
|
const overview = document.getElementById("alarmRank"); |
|
|
|
if (overview) { |
|
|
|
overviewScrollbar = new PerfectScrollbar("#alarmRank", { |
|
|
|
suppressScrollX: true, |
|
|
|
}); |
|
|
|
} |
|
|
|
if (overviewScrollbar && overview) { |
|
|
|
overviewScrollbar.update(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
const interruptDom = document.getElementById("interrupt"); |
|
|
|
if (interrupt && interruptDom) { |
|
|
|
interrupt.update(); |
|
|
|
|
|
|
|
} |
|
|
|
const repairDom = document.getElementById("repair"); |
|
|
|
if (repair && repairDom) { |
|
|
|
interrupt.update(); |
|
|
|
} |
|
|
|
}) |
|
|
|
|
|
|
|
useEffect(() => { |
|
|
|
const maxCombinedValue = mockData?.reduce((max, item) => { |
|
|
|
const combinedMax = Math.max(item.alarmCount, item.dealAlarmCount); |
|
|
|
if (combinedMax > max) { |
|
|
|
return combinedMax; |
|
|
|
} |
|
|
|
return max; |
|
|
|
}, -Infinity) |
|
|
|
const bigD = Math.ceil(maxCombinedValue / 50) * 50 |
|
|
|
if (bigD == 0) { |
|
|
|
setXData([5, 4, 3, 2, 1, 0, 1, 2, 3, 4, 5])//最大值为0,默认横坐标 |
|
|
|
} else { |
|
|
|
setXData([bigD, (bigD - bigD / 5), (bigD - bigD * 2 / 5), (bigD - bigD * 3 / 5), (bigD - bigD * 4 / 5), 0, (bigD - bigD * 4 / 5), (bigD - bigD * 3 / 5), (bigD - bigD * 2 / 5), (bigD - bigD / 5), bigD]) |
|
|
|
} |
|
|
|
setBiggest(bigD) |
|
|
|
if (mockData && mockData.length > 3 && mockData.length < 21) { |
|
|
|
const newArray = mockData.slice(3) |
|
|
|
setAlarmData(newArray) |
|
|
|
} |
|
|
|
if (mockData && mockData.length > 21) { |
|
|
|
//数据大于20的话,取前20 |
|
|
|
const newArray = mockData.slice(3, 20) |
|
|
|
setAlarmData(newArray) |
|
|
|
} |
|
|
|
}, [mockData]) |
|
|
|
|
|
|
|
let statisticOnline = (groupId) => { |
|
|
|
dispatch(actions.projectGroup.groupStatisticOnline({ groupId })).then(res => { |
|
|
|
if (res.success) { |
|
|
|
let Interrupt = [] |
|
|
|
res.payload.data?.forEach(v => { |
|
|
|
if (v.offline?.id) { |
|
|
|
Interrupt.push({ name: v.name, ...v.offline }) |
|
|
|
} |
|
|
|
}) |
|
|
|
Interrupt = Interrupt?.sort((a, b) => b.offline - a.offline) |
|
|
|
setInterruptRank(Interrupt) |
|
|
|
setOnline(res.payload.data?.slice(0, 10) || []) |
|
|
|
setValue(res.payload.data?.map(v => v.id)?.slice(0, 10) || []) |
|
|
|
} |
|
|
|
}) |
|
|
|
} |
|
|
|
|
|
|
|
const timeRequest = (groupId) => { |
|
|
|
// 获取当前时间 |
|
|
|
const currentTime = moment(); |
|
|
|
// 获取下一个小时的时间 |
|
|
|
const nextHour = moment().add(1, 'hour').startOf('hour'); |
|
|
|
// 计算分钟差 |
|
|
|
const minuteDifference = nextHour.diff(currentTime, 'minutes'); |
|
|
|
setTimeout(function () { |
|
|
|
statisticOnline(groupId) |
|
|
|
timeRequest(groupId) |
|
|
|
}, 1000 * 60 * (minuteDifference + 1 || 61)); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
useEffect(() => { |
|
|
|
let count = 0; |
|
|
|
let currentIndex = -1; |
|
|
|
if (!self.current.cityChart) return; |
|
|
|
const timer = setInterval(() => { |
|
|
|
count++; |
|
|
|
if (count == 8) { |
|
|
|
count = 1; |
|
|
|
} |
|
|
|
// 取消之前高亮的图形 |
|
|
|
self.current.cityChart.dispatchAction({ |
|
|
|
type: "downplay", |
|
|
|
seriesIndex: 0, |
|
|
|
dataIndex: currentIndex, |
|
|
|
}); |
|
|
|
currentIndex = |
|
|
|
(currentIndex + 1) % proportion?.length |
|
|
|
// 高亮当前图形 |
|
|
|
self.current.cityChart.dispatchAction({ |
|
|
|
type: "highlight", |
|
|
|
seriesIndex: 0, |
|
|
|
dataIndex: currentIndex, |
|
|
|
}); |
|
|
|
// 显示 label |
|
|
|
self.current.cityChart.dispatchAction({ |
|
|
|
type: "showTip", |
|
|
|
seriesIndex: 0, |
|
|
|
dataIndex: currentIndex, |
|
|
|
}); |
|
|
|
}, 3000); |
|
|
|
|
|
|
|
return () => { |
|
|
|
clearInterval(timer); |
|
|
|
}; |
|
|
|
}, [proportion]); |
|
|
|
|
|
|
|
return ( |
|
|
|
<div className='project-group'> |
|
|
@ -27,72 +190,167 @@ const Bigscreen = ({ dispatch, actions, user, match, history, clientHeight, grou |
|
|
|
<div style={{ width: '100%', height: "45%", display: 'flex' }}> |
|
|
|
<div style={{ width: "calc(50% - 8px)", height: "100%", marginRight: 16, display: 'flex' }}> |
|
|
|
<Card title='项目工单占比' style={{ width: "calc(50% - 8px)", height: "100%", marginRight: 16 }}> |
|
|
|
<div style={{ height: '100%' }}> |
|
|
|
<div style={{ height: '100%', position: 'relative' }}> |
|
|
|
<div style={{ height: clientHeight * 0.55 - 300, display: 'flex', justifyContent: "center", position: 'relative' }}> |
|
|
|
<ReactECharts |
|
|
|
option={{ |
|
|
|
tooltip: { |
|
|
|
show: true, |
|
|
|
trigger: "item", |
|
|
|
position: "right", |
|
|
|
backgroundColor: "rgba(0,0,0,0.7)", |
|
|
|
textStyle: { |
|
|
|
color: "#fff", |
|
|
|
}, |
|
|
|
formatter: (values) => { |
|
|
|
setFormatter(values?.data) |
|
|
|
} |
|
|
|
// `${values.seriesName}<br /> ${values.marker} ${values.name} <b>${values.value}</b>个(${values.percent}%)`, |
|
|
|
}, |
|
|
|
series: [ |
|
|
|
{ |
|
|
|
// name: 'Access From', |
|
|
|
type: 'pie', |
|
|
|
radius: ['60%', '70%'], |
|
|
|
avoidLabelOverlap: false, |
|
|
|
itemStyle: { |
|
|
|
borderRadius: 10, |
|
|
|
borderColor: '#fff', |
|
|
|
borderWidth: 2 |
|
|
|
}, |
|
|
|
label: { |
|
|
|
show: false, |
|
|
|
position: 'center' |
|
|
|
}, |
|
|
|
// emphasis: { |
|
|
|
// label: { |
|
|
|
// show: true, |
|
|
|
// fontSize: 44, |
|
|
|
// fontWeight: 'bold' |
|
|
|
// } |
|
|
|
// }, |
|
|
|
labelLine: { |
|
|
|
show: false |
|
|
|
}, |
|
|
|
data: proportion || [], |
|
|
|
} |
|
|
|
] |
|
|
|
}} |
|
|
|
notMerge |
|
|
|
onChartReady={(instance) => { |
|
|
|
self.current.cityChart = instance; |
|
|
|
}} |
|
|
|
lazyUpdate |
|
|
|
style={{ width: clientHeight * 0.55 - 300, height: clientHeight * 0.55 - 300 }} |
|
|
|
/> |
|
|
|
<img src='/assets/images/projectGroup/chart.png' style={{ height: clientHeight * 0.55 - 330, position: 'absolute', top: 16 }} /> |
|
|
|
<div style={{ position: 'absolute', top: 58, left: "auto", width: 100, textAlign: "center" }}> |
|
|
|
<div style={{ fontFamily: 'DIN-Regular', fontWeight: 400, fontSize: 28, color: '#2F2F2F' }}>{formatter?.value}</div> |
|
|
|
<div style={{ |
|
|
|
width: 100, fontFamily: 'SourceHanSansCN-Regular', fontWeight: 400, |
|
|
|
fontSize: 14, color: '#2C66F3', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' |
|
|
|
}}>{formatter?.name}</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
<div style={{ width: "100%", fontFamily: 'SourceHanSansCN-Regular', fontWeight: 400, fontSize: 14, position: 'absolute', bottom: 10 }}> |
|
|
|
{proportion?.map((v, index) => { |
|
|
|
let color = ['rgb(53 100 209)', 'rgb(138 201 15)', 'rgb(239 204 77)', 'rgb(233 107 107)'] |
|
|
|
return <div style={{ width: "50%", display: 'inline-block' }}> |
|
|
|
<div style={{ display: "flex", justifyContent: "space-between", padding: '0 6px' }}> |
|
|
|
<div title={v.name} style={{ width: 'calc(100% - 40px)', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}> |
|
|
|
<span style={{ background: color[index], display: 'inline-block', marginRight: 6, width: 6, height: 6 }}></span>{v.name}</div> |
|
|
|
<div style={{ width: 34 }}>{v.value}次</div> |
|
|
|
</div> |
|
|
|
|
|
|
|
</div> |
|
|
|
})} |
|
|
|
</div> |
|
|
|
|
|
|
|
</div> |
|
|
|
</Card> |
|
|
|
<Card title='修复排名' style={{ width: "calc(50% - 8px)", height: "100%" }}> |
|
|
|
<div style={{ height: '100%' }}> |
|
|
|
|
|
|
|
|
|
|
|
<div style={{ height: '100%', fontFamily: 'SourceHanSansCN-Regular', fontWeight: 400, fontSize: 14, }}> |
|
|
|
<div style={{ display: "flex", background: '#F6F9FF', height: 40, alignItems: 'center' }}> |
|
|
|
<div style={{ textAlign: 'center', width: '25%' }}>序号</div> |
|
|
|
<div style={{ textAlign: 'center', width: '49%' }}>工单名称</div> |
|
|
|
<div style={{ textAlign: 'center', width: '25%' }}>修复时长</div> |
|
|
|
</div> |
|
|
|
<div id="repair" style={{ position: 'relative', height: clientHeight * 0.55 - 220 }}> |
|
|
|
{groupProject?.map((c, index) => { |
|
|
|
return index < 10 ? <div style={{ display: "flex", background: index % 2 == 1 ? "#F6F9FF" : '', padding: 6, height: 50, alignItems: 'center' }}> |
|
|
|
<div style={{ textAlign: 'center', width: '25%', fontFamily: 'SourceHanSansCN-Regular', color: '#2C66F3', fontWeight: 400 }}> |
|
|
|
NO.{index + 1}</div> |
|
|
|
<div title={c.name || c.pepProjectName + "(售后工单)"} style={{ textAlign: 'center', padding: '0 6px', width: '49%', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}> |
|
|
|
{c.name || c.pepProjectName}(售后工单)</div> |
|
|
|
<div style={{ textAlign: 'center', width: '25%', fontFamily: 'SourceHanSansCN-Regular', fontWeight: 400 }}> |
|
|
|
{c.value}h</div> |
|
|
|
</div> : <></> |
|
|
|
})} |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</Card> |
|
|
|
</div> |
|
|
|
<Card title='数据在线率' style={{ width: "calc(50% - 8px)", height: "100%", }}> |
|
|
|
<div style={{ height: '100%' }}> |
|
|
|
|
|
|
|
<div style={{ height: '100%', position: 'relative' }}> |
|
|
|
{/* <div > */} |
|
|
|
<Select |
|
|
|
showClear |
|
|
|
filter |
|
|
|
value={value} |
|
|
|
multiple={true} |
|
|
|
maxTagCount={1} |
|
|
|
style={{ width: 300, position: 'absolute', top: 0, right: 0, zIndex: 99 }} |
|
|
|
optionList={groupStatisticOnline?.map(v => ({ value: v.id, label: v.name })) || []} |
|
|
|
onChange={v => { |
|
|
|
setValue(v) |
|
|
|
setOnline(groupStatisticOnline?.filter(s => v.includes(s.id))) |
|
|
|
}} |
|
|
|
/> |
|
|
|
{/* </div> */} |
|
|
|
<ReactECharts |
|
|
|
option={{ |
|
|
|
title: { |
|
|
|
// text: v.name, |
|
|
|
}, |
|
|
|
grid: { |
|
|
|
// width: 300, |
|
|
|
// height: 200 |
|
|
|
left: 27, |
|
|
|
right: 10, |
|
|
|
bottom: 20, |
|
|
|
}, |
|
|
|
// dataZoom: [ |
|
|
|
// { |
|
|
|
// type: 'slider', |
|
|
|
// showDetail: false |
|
|
|
// }, |
|
|
|
// { |
|
|
|
// type: 'inside', |
|
|
|
|
|
|
|
// }, |
|
|
|
// ], |
|
|
|
tooltip: { |
|
|
|
trigger: 'axis' |
|
|
|
}, |
|
|
|
legend: { |
|
|
|
data: groupStatisticOnline?.map(v => v.name) || [], |
|
|
|
right: '10%', |
|
|
|
textStyle: { |
|
|
|
color: '#FFF', |
|
|
|
}, |
|
|
|
trigger: 'axis', |
|
|
|
formatter: function (params) { |
|
|
|
// 自定义提示框内容 |
|
|
|
// console.log(params); |
|
|
|
let title = params[0].data[0] + '<br/>' + '<br/>' |
|
|
|
params.forEach(v => { |
|
|
|
let find = online?.find(s => s.name == v.seriesName)?.online?.find(d => moment(d.collect_time).format('YYYY-MM-DD HH') == v.data[0]) || {} |
|
|
|
title = title + v.seriesName + ":" + " " + " " + v.data[1] + "%" + "(" + find?.online + "/" + find?.total + ")" + '<br/>' |
|
|
|
}) |
|
|
|
return title |
|
|
|
} |
|
|
|
}, |
|
|
|
xAxis: { |
|
|
|
type: 'time', |
|
|
|
// name: "时间", |
|
|
|
boundaryGap: false, |
|
|
|
minInterval: 1000 * 60, |
|
|
|
|
|
|
|
minInterval: 1000 * 60 * 60, |
|
|
|
}, |
|
|
|
yAxis: { |
|
|
|
type: 'value', |
|
|
|
name: "单位:A", |
|
|
|
name: "单位%", |
|
|
|
areaStyle: { |
|
|
|
color: '#FFF', |
|
|
|
}, |
|
|
|
}, |
|
|
|
series: groupStatisticOnline?.map(v => ({ |
|
|
|
series: online?.map(v => ({ |
|
|
|
type: 'line', |
|
|
|
name: v.name, |
|
|
|
smooth: true, |
|
|
|
areaStyle: { |
|
|
|
color: '#0e9cff26', |
|
|
|
}, |
|
|
|
data: v.online?.map(f => [moment(f.collect_time).format('YYYY-MM-DD HH'), f.rate]) || [] |
|
|
|
data: v.online?.map(f => [moment(f.collect_time).format('YYYY-MM-DD HH'), f.rate.toFixed(1)]) || [] |
|
|
|
})) || [] |
|
|
|
}} |
|
|
|
notMerge={true} |
|
|
@ -100,28 +358,142 @@ const Bigscreen = ({ dispatch, actions, user, match, history, clientHeight, grou |
|
|
|
style={{ width: "100%", height: "100%" }} |
|
|
|
theme={'ReactEChart'} |
|
|
|
/> |
|
|
|
|
|
|
|
</div> |
|
|
|
</Card> |
|
|
|
|
|
|
|
</div> |
|
|
|
<div style={{ width: '100%', height: "calc(55% - 24px)", display: 'flex', marginTop: 24 }}> |
|
|
|
<Card title='告警排名TOP20' style={{ width: "calc(50% - 8px)", height: "100%", marginRight: 16, }}> |
|
|
|
<div style={{ height: '100%' }}> |
|
|
|
<Card title='告警排名TOP20' style={{ |
|
|
|
width: "calc(50% - 8px)", height: "100%", marginRight: 16 |
|
|
|
}} > |
|
|
|
{mockData && mockData.length > 0 ? (<div style={{ height: '100%' }}> |
|
|
|
<div style={{ display: "flex", justifyContent: 'flex-end' }}> |
|
|
|
<div style={{ display: "flex", alignItems: 'center' }}> |
|
|
|
<div class='alarmDiv'></div><div class='alarm'>超阈值个数</div> |
|
|
|
</div> |
|
|
|
<div style={{ display: "flex", alignItems: 'center' }}> |
|
|
|
<div class='dealAlarmCountDiv'></div><div class='alarmCount'>手动恢复个数</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
<div id='alarmRank' style={{ height: clientHeight * 0.55 - 150, position: 'relative' }}> |
|
|
|
|
|
|
|
{mockData && mockData[0] ? (<div style={{ display: 'flex', marginTop: 15, alignItems: 'center' }}> |
|
|
|
<div class='rankDiv'> |
|
|
|
<img src='/assets/images/projectGroup/first.png'></img> |
|
|
|
</div> |
|
|
|
<div class='structDiv'>{mockData[0]?.name?.length > 5 ? <Tooltip content={mockData[0]?.name}>{mockData[0]?.name.substring(0, 5) + '...'}</Tooltip> : mockData[0]?.name}</div> |
|
|
|
<div class='barChartDiv'> |
|
|
|
<div style={{ width: '50%', display: 'flex', justifyContent: 'flex-end' }}> |
|
|
|
<div class='alarms' style={{ width:(biggest>0? ((mockData[0].dealAlarmCount / biggest) * 100 + '%'):0), height: '100%' }}></div> |
|
|
|
</div> |
|
|
|
<div style={{ width: '50%', display: 'flex', }}> |
|
|
|
<div class='dealAlarms' style={{ width: (biggest>0? ((mockData[0].alarmCount / biggest) * 100 + '%'):0), height: '100%' }}></div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div>) : '' |
|
|
|
} |
|
|
|
{mockData && mockData[1] ? (<div style={{ display: 'flex', marginTop: 5, alignItems: 'center' }}> |
|
|
|
<div class='rankDiv'> |
|
|
|
<img src='/assets/images/projectGroup/second.png'></img> |
|
|
|
</div> |
|
|
|
<div class='structDiv'>{mockData[1]?.name?.length > 5 ? <Tooltip content={mockData[1]?.name}>{mockData[1]?.name.substring(0, 5) + '...'}</Tooltip> : mockData[0]?.name}</div> |
|
|
|
<div class='barChartDiv'> |
|
|
|
<div style={{ width: '50%', display: 'flex', justifyContent: 'flex-end' }}> |
|
|
|
<div class='alarms' style={{ width: (biggest>0? ((mockData[1].dealAlarmCount / biggest) * 100 + '%'):0), height: '100%' }}></div> |
|
|
|
</div> |
|
|
|
<div style={{ width: '50%', display: 'flex', }}> |
|
|
|
<div class='dealAlarms' style={{ width: (biggest>0? ((mockData[1].alarmCount / biggest) * 100 + '%'):0), height: '100%' }}></div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div>) : '' |
|
|
|
} |
|
|
|
{mockData && mockData[2] ? (<div style={{ display: 'flex', marginTop: 5, alignItems: 'center' }}> |
|
|
|
<div class='rankDiv'> |
|
|
|
<img src='/assets/images/projectGroup/third.png'></img> |
|
|
|
</div> |
|
|
|
<div class='structDiv'>{mockData[2]?.name?.length > 5 ? <Tooltip content={mockData[2]?.name}>{mockData[2]?.name.substring(0, 5) + '...'}</Tooltip> : mockData[0]?.name}</div> |
|
|
|
<div class='barChartDiv'> |
|
|
|
<div style={{ width: '50%', display: 'flex', justifyContent: 'flex-end' }}> |
|
|
|
<div class='alarms' style={{ width: (biggest>0? ((mockData[2].dealAlarmCount / biggest) * 100 + '%'):0), height: '100%' }}></div> |
|
|
|
</div> |
|
|
|
<div style={{ width: '50%', display: 'flex', }}> |
|
|
|
<div class='dealAlarms' style={{ width:(biggest>0? ((mockData[2].alarmCount / biggest) * 100 + '%'):0), height: '100%' }}></div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div>) : '' |
|
|
|
} |
|
|
|
{alarmData && alarmData.length ? |
|
|
|
alarmData.map((item, index) => { |
|
|
|
return (<div style={{ display: 'flex', marginTop: 5, alignItems: 'center' }}> |
|
|
|
<div class='rankDiv'> |
|
|
|
<span>{index + 4}</span> |
|
|
|
</div> |
|
|
|
<div class='structDiv'>{item.name?.length > 5 ? <Tooltip content={item.name}>{item.name.substring(0, 5) + '...'}</Tooltip> : item.name}</div> |
|
|
|
<div class='barChartDiv'> |
|
|
|
<div style={{ width: '50%', display: 'flex', justifyContent: 'flex-end' }}> |
|
|
|
<div class='alarms' style={{ width:(biggest>0?((item.dealAlarmCount / biggest) * 100 + '%'):0), height: '100%' }}></div> |
|
|
|
</div> |
|
|
|
<div style={{ width: '50%', display: 'flex', }}> |
|
|
|
<div class='dealAlarms' style={{ width:(biggest>0? ((item.alarmCount / biggest) * 100 + '%'):0), height: '100%' }}></div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
|
|
|
|
</div> |
|
|
|
</div>) |
|
|
|
} |
|
|
|
) |
|
|
|
: '' |
|
|
|
} |
|
|
|
</div> |
|
|
|
<div class="scale"> |
|
|
|
{xData?.map(item => { |
|
|
|
return <div >{item}</div> |
|
|
|
})} |
|
|
|
</div> |
|
|
|
</div>) : ''} |
|
|
|
</Card> |
|
|
|
<Card title='中断排名' style={{ width: "calc(50% - 8px)", height: "100%", }}> |
|
|
|
<div style={{ height: '100%' }}> |
|
|
|
|
|
|
|
<div style={{ height: '100%', fontFamily: 'SourceHanSansCN-Regular', fontWeight: 400, fontSize: 14, }}> |
|
|
|
<div style={{ display: "flex", background: '#F6F9FF', height: 40, alignItems: 'center' }}> |
|
|
|
<div style={{ textAlign: 'center', width: '33%' }}>结构物</div> |
|
|
|
<div style={{ textAlign: 'center', width: '33%' }}>中断时长</div> |
|
|
|
<div style={{ textAlign: 'center', width: '33%' }}>中断个数</div> |
|
|
|
</div> |
|
|
|
<div id="interrupt" style={{ position: 'relative', height: clientHeight * 0.55 - 170 }}> |
|
|
|
{InterruptRank?.map((c, index) => { |
|
|
|
let title |
|
|
|
if (c.offline) { |
|
|
|
if (c.offline >= 1440 && Math.floor(c.offline / 1440)) title = Math.floor(c.offline / 1440) + "天" |
|
|
|
if ((c.offline % 1440) >= 60 && Math.floor(c.offline % 1440 / 60)) { |
|
|
|
if (title) { |
|
|
|
title = title + Math.floor(c.offline % 1440 / 60) + "时" |
|
|
|
} else { |
|
|
|
title = Math.floor(c.offline % 1440 / 60) + "时" |
|
|
|
} |
|
|
|
} |
|
|
|
if (c.offline % 1440 % 60) { |
|
|
|
if (title) { |
|
|
|
title = title + c.offline % 1440 % 60 + "分" |
|
|
|
} else { |
|
|
|
title = c.offline % 1440 % 60 + "分" |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
return <div style={{ display: "flex", background: index % 2 == 1 ? "#F6F9FF" : '', height: 40, alignItems: 'center' }}> |
|
|
|
<div style={{ textAlign: 'center', width: '33%', fontFamily: 'SourceHanSansCN-Regular', color: '#2C66F3', fontWeight: 400 }}>{c.name}</div> |
|
|
|
<div style={{ textAlign: 'center', width: '33%' }}>{title}</div> |
|
|
|
<div style={{ textAlign: 'center', width: '33%', fontFamily: 'SourceHanSansCN-Regular', color: '#F33B3B', fontWeight: 400 }}>{c.offnum + '/' + c.totnum}</div> |
|
|
|
</div> |
|
|
|
})} |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</Card> |
|
|
|
</div> |
|
|
|
|
|
|
|
</div> |
|
|
|
</div > |
|
|
|
|
|
|
|
</Body> |
|
|
|
</div> |
|
|
|
</Body > |
|
|
|
</div > |
|
|
|
) |
|
|
|
} |
|
|
|
|
|
|
@ -135,4 +507,4 @@ function mapStateToProps (state) { |
|
|
|
}; |
|
|
|
} |
|
|
|
|
|
|
|
export default connect(mapStateToProps)(Bigscreen); |
|
|
|
export default connect(mapStateToProps)(Bigscreen); |