|
|
@ -1,5 +1,6 @@ |
|
|
|
import React, { useEffect, useRef, useState } from 'react'; |
|
|
|
import { Skeleton, Button, Pagination, Select, Popconfirm, Table, Tooltip } from '@douyinfe/semi-ui'; |
|
|
|
import { Skeleton, Button, Pagination, Select, Popconfirm, Table, Tooltip,Tabs,TabPane} from '@douyinfe/semi-ui'; |
|
|
|
import { IconChevronUpDown,IconChevronUp,IconChevronDown } from '@douyinfe/semi-icons' |
|
|
|
import { connect } from 'react-redux'; |
|
|
|
import { push } from 'react-router-redux'; |
|
|
|
import Header from '../components/header'; |
|
|
@ -31,7 +32,9 @@ const Bigscreen = (props) => { |
|
|
|
const [mockData, setMockData] = useState()//所有的告警数据 |
|
|
|
const [xData, setXData] = useState([])//横坐标 |
|
|
|
const self = useRef({ myChart: null }); |
|
|
|
|
|
|
|
const [state, setState] = useState(0) |
|
|
|
const [interruptData,setInterruptData]=useState([]) |
|
|
|
const [avgTmes,setAvgTimes]=useState([])//平均修复时长数组 |
|
|
|
// const [queryUserId, setQueryUserId] = useState('') |
|
|
|
|
|
|
|
useEffect(() => { |
|
|
@ -148,9 +151,11 @@ const Bigscreen = (props) => { |
|
|
|
dispatch(actions.projectGroup.getProjectWorkOrders({ projectIds: query })).then(res => { |
|
|
|
if (res.success) { |
|
|
|
setProportion([...res.payload.data?.slice(0, 3)?.map(v => ({ name: allProjects?.find(item => item.value === v.projectId)?.label, value: Number(v.count) })), |
|
|
|
{ name: '其它', value: res.payload.data&&res.payload.data.length>3?res.payload.data?.slice(3)?.reduce((p,c)=>{ |
|
|
|
{ |
|
|
|
name: '其它', value: res.payload.data && res.payload.data.length > 3 ? res.payload.data?.slice(3)?.reduce((p, c) => { |
|
|
|
return p + Number(c.count) |
|
|
|
},0):0 }]) |
|
|
|
}, 0) : 0 |
|
|
|
}]) |
|
|
|
} |
|
|
|
}) |
|
|
|
dispatch(actions.projectGroup.getWorkOrdersRepairRank({ projectIds: query })).then(res => { |
|
|
@ -158,10 +163,20 @@ const Bigscreen = (props) => { |
|
|
|
setGroupProject(res.payload.data?.slice(0, 10).map(v => ({ name: v.formname, startTime: moment(v?.startTime).format('YYYY-MM-DD'), duration: moment(v?.endTime).add(8, 'hours').diff(v?.startTime, 'hours') })) || []) |
|
|
|
} |
|
|
|
}) |
|
|
|
|
|
|
|
//修复平均时长 |
|
|
|
dispatch(actions.projectGroup.getWorkOrdersAvgTimes({ projectIds: query })).then(res=>{ |
|
|
|
if (res.success) { |
|
|
|
const data=res.payload.data?.map(v=>{ |
|
|
|
return {projectName:allProjects?.find(item => item.value == v.project_id)?.label, |
|
|
|
avgTime: Math.ceil(v.avgTime / 60 / 60), |
|
|
|
project_id:v.project_id |
|
|
|
} |
|
|
|
}) |
|
|
|
setAvgTimes(data) |
|
|
|
} |
|
|
|
}) |
|
|
|
} |
|
|
|
}, [groupDetail, allProjects]) |
|
|
|
|
|
|
|
let statisticOnline = (groupId) => { |
|
|
|
dispatch(actions.projectGroup.groupStatisticOnline({ groupId })).then(res => { |
|
|
|
if (res.success) { |
|
|
@ -171,8 +186,9 @@ const Bigscreen = (props) => { |
|
|
|
Interrupt.push({ name: v.name, ...v.offline }) |
|
|
|
} |
|
|
|
}) |
|
|
|
Interrupt = Interrupt?.sort((a, b) => b.offline - a.offline) |
|
|
|
Interrupt = Interrupt?.sort((a, b) =>a.offnum/a.totnum- b.offnum/b.totnum) |
|
|
|
setInterruptRank(Interrupt) |
|
|
|
setInterruptData(Interrupt) |
|
|
|
setOnline(res.payload.data?.slice(0, 10) || []) |
|
|
|
setValue(res.payload.data?.map(v => v.id)?.slice(0, 10) || []) |
|
|
|
} |
|
|
@ -191,8 +207,41 @@ const Bigscreen = (props) => { |
|
|
|
timeRequest(groupId) |
|
|
|
}, 1000 * 60 * (minuteDifference + 1 || 61)); |
|
|
|
} |
|
|
|
//中断排名排序相关 |
|
|
|
const topClick=(e)=>{ |
|
|
|
let data=[] |
|
|
|
interruptData.map(v=>{data.push(v)}) |
|
|
|
switch (e) { |
|
|
|
case 'perBottom': |
|
|
|
setInterruptRank(data.sort((a, b) => b.offnum/b.totnum-a.offnum/a.totnum)) |
|
|
|
setState(1) |
|
|
|
break; |
|
|
|
case 'perTop': |
|
|
|
setInterruptRank(data.sort((a, b) => a.offnum/a.totnum - b.offnum/b.totnum)) |
|
|
|
setState(0) |
|
|
|
break; |
|
|
|
case 'timeBottom': |
|
|
|
setInterruptRank(data.sort((a, b) => b.offline-a.offline )) |
|
|
|
setState(3) |
|
|
|
break; |
|
|
|
case 'timeTop': |
|
|
|
setInterruptRank(data.sort((a, b) => a.offline - b.offline )) |
|
|
|
setState(2) |
|
|
|
break; |
|
|
|
case 'countBottom': |
|
|
|
setInterruptRank(data.sort((a, b) => b.totnum-a.totnum )) |
|
|
|
setState(5) |
|
|
|
break; |
|
|
|
case 'countTop': |
|
|
|
setInterruptRank(data.sort((a, b) => a.totnum-b.totnum )) |
|
|
|
setState(4) |
|
|
|
break; |
|
|
|
default: |
|
|
|
return |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// console.log('sortOrder',sortOrder) |
|
|
|
useEffect(() => { |
|
|
|
let count = 0; |
|
|
|
let currentIndex = -1; |
|
|
@ -235,7 +284,92 @@ const Bigscreen = (props) => { |
|
|
|
<Body> |
|
|
|
<div style={{ width: "100%", height: '100%' }}> |
|
|
|
<div style={{ width: '100%', height: "45%", display: 'flex' }}> |
|
|
|
<div style={{ width: "calc(50% - 8px)", height: "100%", marginRight: 16, display: 'flex' }}> |
|
|
|
<Card title='数据在线率' tooltipContent='在线率计算:设备存活/总设备(存活判断:普通设备2h以内有实时数据,GNSS设备8h以内有实时数据)' style={{ width: "calc(50% - 8px)", 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: { |
|
|
|
left: 27, |
|
|
|
right: 10, |
|
|
|
bottom: 20, |
|
|
|
}, |
|
|
|
tooltip: { |
|
|
|
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 * 60, |
|
|
|
}, |
|
|
|
dataZoom:[ |
|
|
|
{ |
|
|
|
show: true, |
|
|
|
realtime: true, |
|
|
|
start: 0, |
|
|
|
end: 100 |
|
|
|
}, |
|
|
|
{ |
|
|
|
type: 'inside', |
|
|
|
realtime: true, |
|
|
|
start: 0, |
|
|
|
end: 100 |
|
|
|
} |
|
|
|
], |
|
|
|
yAxis: { |
|
|
|
type: 'value', |
|
|
|
name: "单位%", |
|
|
|
areaStyle: { |
|
|
|
color: '#FFF', |
|
|
|
}, |
|
|
|
}, |
|
|
|
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.toFixed(1)]) || [] |
|
|
|
})) || [] |
|
|
|
}} |
|
|
|
notMerge={true} |
|
|
|
lazyUpdate={true} |
|
|
|
style={{ width: "100%", height: "100%" }} |
|
|
|
theme={'ReactEChart'} |
|
|
|
/> |
|
|
|
|
|
|
|
</div> |
|
|
|
</Card> |
|
|
|
<div style={{ width: "calc(50% - 8px)", height: "100%", marginLeft: 16, display: 'flex' }}> |
|
|
|
<Card title='项目工单占比' tooltipContent='项目工单占比:一个月内项目发起工单修复的次数占比。' style={{ width: "calc(50% - 8px)", height: "100%", marginRight: 16 }}> |
|
|
|
<div style={{ height: '100%', position: 'relative' }}> |
|
|
|
<div style={{ height: clientHeight * 0.55 - 300, display: 'flex', justifyContent: "center", position: 'relative' }}> |
|
|
@ -315,14 +449,17 @@ const Bigscreen = (props) => { |
|
|
|
|
|
|
|
</div> |
|
|
|
</Card> |
|
|
|
<Card title='修复排名' tooltipContent='修复时间排名:一个月内,计算每个工单的修复时间' style={{ width: "calc(50% - 8px)", height: "100%" }}> |
|
|
|
<Card title='修复排名' style={{ width: "calc(50% - 8px)", height: "100%" }} tooltipContent='修复时间排名:一个月内,计算每个工单的修复时间'> |
|
|
|
<Tabs type="line"> |
|
|
|
<TabPane tab="修复排名" itemKey="1"> |
|
|
|
|
|
|
|
<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 }}> |
|
|
|
<div id="repair" style={{ position: 'relative', height: clientHeight * 0.55 - 220 - 52 }}> |
|
|
|
<AutoRollComponent content={<> {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 }}> |
|
|
@ -337,25 +474,10 @@ const Bigscreen = (props) => { |
|
|
|
|
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</Card> |
|
|
|
</div> |
|
|
|
<Card title='数据在线率' tooltipContent='在线率计算:设备存活/总设备(存活判断:普通设备2h以内有实时数据,GNSS设备8h以内有实时数据)' style={{ width: "calc(50% - 8px)", 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> */} |
|
|
|
</TabPane> |
|
|
|
<TabPane tab="项目统计" itemKey="2"> |
|
|
|
<div style={{ height: clientHeight * 0.55 - 220 - 52, fontFamily: 'SourceHanSansCN-Regular', fontSize: 14,width:'100%' }}> |
|
|
|
|
|
|
|
<ReactECharts |
|
|
|
option={{ |
|
|
|
title: { |
|
|
@ -367,54 +489,100 @@ const Bigscreen = (props) => { |
|
|
|
bottom: 20, |
|
|
|
}, |
|
|
|
tooltip: { |
|
|
|
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 |
|
|
|
} |
|
|
|
// trigger: 'axis', |
|
|
|
position: ['5%', '50%'] , |
|
|
|
|
|
|
|
}, |
|
|
|
xAxis: { |
|
|
|
type: 'time', |
|
|
|
// name: "时间", |
|
|
|
boundaryGap: false, |
|
|
|
minInterval: 1000 * 60 * 60, |
|
|
|
show:true, |
|
|
|
type: 'category', |
|
|
|
data: avgTmes?.map(s => s.projectName), |
|
|
|
axisLabel: { |
|
|
|
formatter: function (value) { |
|
|
|
// 控制显示前五个字符,其余用省略号代替 |
|
|
|
return value.substring(0, 5) + (value.length > 5 ? '...' : ''); |
|
|
|
}, |
|
|
|
yAxis: { |
|
|
|
type: 'value', |
|
|
|
name: "单位%", |
|
|
|
areaStyle: { |
|
|
|
color: '#FFF', |
|
|
|
}, |
|
|
|
}, |
|
|
|
series: online?.map(v => ({ |
|
|
|
type: 'line', |
|
|
|
name: v.name, |
|
|
|
smooth: true, |
|
|
|
areaStyle: { |
|
|
|
color: '#0e9cff26', |
|
|
|
yAxis: { |
|
|
|
type: 'value', |
|
|
|
name: "单位(小时)", |
|
|
|
// areaStyle: { |
|
|
|
// color: '#FFF', |
|
|
|
// }, |
|
|
|
}, |
|
|
|
data: v.online?.map(f => [moment(f.collect_time).format('YYYY-MM-DD HH'), f.rate.toFixed(1)]) || [] |
|
|
|
})) || [] |
|
|
|
series: [ |
|
|
|
{ |
|
|
|
type: 'bar', |
|
|
|
data: avgTmes?.map(s => s.avgTime), |
|
|
|
} |
|
|
|
] |
|
|
|
}} |
|
|
|
notMerge={true} |
|
|
|
// notMerge={true} |
|
|
|
lazyUpdate={true} |
|
|
|
style={{ width: "100%", height: "100%" }} |
|
|
|
theme={'ReactEChart'} |
|
|
|
/> |
|
|
|
|
|
|
|
</div> |
|
|
|
</TabPane> |
|
|
|
</Tabs> |
|
|
|
</Card> |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
|
|
</div> |
|
|
|
<div style={{ width: '100%', height: "calc(55% - 24px)", display: 'flex', marginTop: 24 }}> |
|
|
|
|
|
|
|
<Card title='中断排名' tooltipContent='中断时长:当前时间-最后一条数据时间。中断个数:结构物下中断测点个数/结构物总测点个数。' style={{ width: "calc(50% - 8px)", 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%', position: 'relative' }}>中断百分比<i class="angle_top" id={state==0?'angleSelected':null} onClick={()=>topClick('perTop')}></i><i id={state==1?'angleSelected':null} class="angle_bottom" onClick={()=>topClick('perBottom')}></i> </div> |
|
|
|
<div style={{ textAlign: 'center', width: '33%', position: 'relative' }}>中断时长<i class="angle_top" id={state==2?'angleSelected':null} onClick={()=>topClick('timeTop')}></i><i id={state==3?'angleSelected':null} class="angle_bottom" onClick={()=>topClick('timeBottom')}></i></div> |
|
|
|
<div style={{ textAlign: 'center', width: '33%', position: 'relative' }}>中断个数<i class="angle_top" id={state==4?'angleSelected':null} onClick={()=>topClick('countTop')}></i><i id={state==5?'angleSelected':null} class="angle_bottom" onClick={()=>topClick('countBottom')}></i></div> |
|
|
|
</div> |
|
|
|
<div id="interrupt" style={{ position: 'relative', height: clientHeight * 0.55 - 170 }}> |
|
|
|
<AutoRollComponent content={<> |
|
|
|
{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 + "分" |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
//判断中断时长是否超过两百天 |
|
|
|
const cc = title.split('天') |
|
|
|
if (cc.length > 1) { |
|
|
|
if (Number(cc[0]) > 200) { |
|
|
|
return |
|
|
|
} |
|
|
|
} |
|
|
|
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%', fontFamily: 'SourceHanSansCN-Regular', color: '#F33B3B', fontWeight: 400 }}>{((c.offnum / c.totnum) * 100).toFixed(2)}%</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> |
|
|
|
})}</>} containerStyle={{ position: "relative", height: "85%", }} |
|
|
|
divHeight={"100%"} divId={"interruptchart"} /> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</Card> |
|
|
|
<Card title='告警排名TOP20' tooltipContent='(1)超阈值个数:一周内结构物超阈值告警的个数。(2)手动恢复个数:一个月内超阈值告警手动恢复的个数' style={{ |
|
|
|
width: "calc(50% - 8px)", height: "100%", marginRight: 16 |
|
|
|
width: "calc(50% - 8px)", height: "100%", marginLeft: 16 |
|
|
|
}} > |
|
|
|
{alarmData && alarmData.length > 0 ? (<div style={{ height: '100%' }}> |
|
|
|
<div style={{ display: "flex", justifyContent: 'flex-end' }}> |
|
|
@ -458,46 +626,6 @@ const Bigscreen = (props) => { |
|
|
|
</div> |
|
|
|
</div>) : ''} |
|
|
|
</Card> |
|
|
|
<Card title='中断排名' tooltipContent='中断时长:当前时间-最后一条数据时间。中断个数:结构物下中断测点个数/结构物总测点个数。' style={{ width: "calc(50% - 8px)", 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 }}> |
|
|
|
<AutoRollComponent content={<> |
|
|
|
{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+`(${((c.offnum/c.totnum)*100).toFixed(2)}%)`}</div> |
|
|
|
</div> |
|
|
|
})}</> } containerStyle={{ position: "relative", height: "85%", }} |
|
|
|
divHeight={"100%"} divId={"interruptchart"}/> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</Card> |
|
|
|
</div> |
|
|
|
|
|
|
|
</div > |
|
|
|