Browse Source

(*)首页图表 代码暂交

master
wuqun 2 years ago
parent
commit
e8a6d6059c
  1. 62
      web/client/src/sections/shouye/components/alarm/alarmStatistics.js
  2. 138
      web/client/src/sections/shouye/components/alarm/autorollcomponent.js
  3. 80
      web/client/src/sections/shouye/components/charts/column.js
  4. 107
      web/client/src/sections/shouye/components/charts/stackColumn.js
  5. 85
      web/client/src/sections/shouye/components/charts/xColumn.js
  6. 158
      web/client/src/sections/shouye/containers/shouye.js
  7. 16
      web/client/src/sections/shouye/style.less

62
web/client/src/sections/shouye/components/alarm/alarmStatistics.js

@ -0,0 +1,62 @@
'use strict'
import React, { Component } from 'react';
import { Row, Col, Tooltip } from 'antd';
import AutoRollComponent from './autorollcomponent';
class AlarmStatistics extends Component {
constructor(props) {
super(props);
this.state = {
workers: {
wTypePieData: [
{ item: '点位1', count: 214 },
{ item: '点位2', count: 135 },
{ item: '点位3', count: 88 },
{ item: '点位4', count: 63 },
{ item: '点位5', count: 56 },
{ item: '点位6', count: 115 },
{ item: '点位7', count: 67 },
{ item: '点位8', count: 144 },
{ item: '点位9', count: 21 },
{ item: '点位10', count: 83 },
]
}
}
}
render() {
const { height } = this.props;
const { workers } = this.state;
let max = null, content = null;
let data = workers.wTypePieData.sort((a, b) => b.count - a.count);
max = data[0].count;
content = <div style={{ padding: '0px 10px 30px 30px' }}>
{
workers.wTypePieData.map((wd, i) => {
let cls = i < 3 ? 'alarm-row rank1' : 'alarm-row rank2';
return <Row style={{ marginBottom: 15 }}>
<Col offset={1} span={3}><span className={cls}>No.{i + 1}</span></Col>
<Col offset={1} span={15}>{wd.item}</Col>
<Col span={4}>{wd.count}</Col>
</Row>
})
}
</div>
return (
<div>
<div style={{ fontWeight: 'bold', fontSize: 18 }}>
告警统计
</div>
<div style={{ marginTop: 20 }}>
{
content ? <AutoRollComponent content={content} divHeight={height} divId={"type-list"} />
: <div style={{ border: '1px dashed #999', width: '100%', height: height, paddingTop: height * 0.45, textAlign: 'center' }}>
暂无数据
</div>
}
</div>
</div>
);
}
}
export default AlarmStatistics;

138
web/client/src/sections/shouye/components/alarm/autorollcomponent.js

@ -0,0 +1,138 @@
'use strict'
import React, { Component } from 'react';
import { Row, Col } from 'antd';
export default class AutoRollComponent extends Component {
constructor(props) {
super(props);
this.scrollElem = null;
this.stopscroll = false;
this.preTop = 0;
this.cloneEle = null;
this.currentTop = 0;
this.marqueesHeight = 0;
this.interval = null;
this.state = {
enabledScroll: false
}
}
get enabledScroll() {
let scrollElem = document.getElementById(this.props.divId);
let fatherElem = scrollElem?.parentNode || null;
if (scrollElem && fatherElem) {
return scrollElem.scrollHeight > fatherElem.scrollHeight
}
return false;
}
marque = (height) => {
try {
this.scrollElem = document.getElementById(this.props.divId);
this.marqueesHeight = height;
if (this.scrollElem) {
this.scrollElem.style.height = this.marqueesHeight;
this.scrollElem.style.overflow = 'hidden';
}
this.repeat();
} catch (e) { console.log(e) }
}
repeat = () => {
this.scrollElem.scrollTop = 0;
this.interval = setInterval(() => {
if (this.stopscroll) return;
this.currentTop = this.currentTop + 1;
this.preTop = this.scrollElem.scrollTop;
this.scrollElem.scrollTop = this.scrollElem.scrollTop + 1;
// console.log(`this.scrollElem.scrollTop:${this.scrollElem.scrollTop} === this.preTop:${this.preTop}`);
if (this.preTop === this.scrollElem.scrollTop) {
this.scrollElem.scrollTop = this.marqueesHeight;
this.scrollElem.scrollTop = this.scrollElem.scrollTop + 1;
}
}, 80);
}
componentWillUnmount() {
clearInterval(this.interval);
}
componentWillReceiveProps(nextProps) {
requestAnimationFrame(() => {
if (this.enabledScroll) {
if (!this.state.enabledScroll) {
this.setState({ enabledScroll: true }, () => {
this.marque(10)
})
}
}
})
}
componentDidMount() {
if (this.enabledScroll) {
this.setState({ enabledScroll: true }, () => {
this.marque(10)
})
}
}
onMouseOver = () => {
this.stopscroll = true;
}
onMouseOut = () => {
this.stopscroll = false;
}
render() {
const { headStyle = headStyle || {}, changeStyleCol, heads, spans, data, divId, divHeight, content, containerStyle = {} } = this.props;
return (
<div style={{ ...containerStyle, textAlign: 'left' }}>
{
heads ?
<Row style={{ ...headStyle, lineHeight: '40px', height: 40 }}>
{heads.map((c, index) => {
return <Col span={spans[index]} key={index}>{c}</Col>
})
}
</Row> : ''
}
<div id={divId} style={{ overflow: 'hidden', height: divHeight }} onMouseOver={this.onMouseOver} onMouseOut={this.onMouseOut}>
<div>
{content ? content : ''}
{this.state.enabledScroll && content ? content : ''}
{
data ?
data.map((q, idx) => {
return (
<div key={idx}>
<Row gutter={16} style={{ borderBottom: '0px solid grey' }}>
{heads.map((c, index) => {
return <Col span={spans[index]} key={index} style={{ paddingTop: 8, textAlign: 'left', wordBreak: 'break-word', color: `${c === changeStyleCol ? q.changeColor : ''}` }}>
{index == 1 ? q.data[index] == -1 ? "-" : q.data[index] : index == 2 ? q.data[1] == -1 ? '-' : q.data[index] : q.data[index]}</Col>
})
}
</Row>
</div>
)
}) : ''
}
<div style={{ margin: 16 }}></div>
</div>
</div>
</div >
)
}
}

80
web/client/src/sections/shouye/components/charts/column.js

@ -0,0 +1,80 @@
import React, { Component } from 'react';
import * as echarts from 'echarts';
class ColumnChart extends Component {
constructor(props) {
super(props);
this.state = {
};
}
componentDidMount() {
const { xAxis, datas, domId } = this.props;
this.createCharts(xAxis, datas, domId);
}
componentWillReceiveProps(nextProps) {
let { xAxis, datas, domId } = nextProps;
if (JSON.stringify(xAxis) != JSON.stringify(this.props.xAxis) || JSON.stringify(datas) != JSON.stringify(this.props.datas)) {
this.createCharts(xAxis, datas, domId);
}
}
createCharts = (xAxis, datas, domId) => {
this.clearEchart();
let chartDom = document.getElementById(domId);
this.chart = echarts.init(chartDom);
let option = this.getOption(xAxis, datas);
this.chart.setOption(option);
this.onSize = () => {
this.chart.resize();
}
window.addEventListener("resize", this.onSize);
};
// 组件销毁删除监听
componentWillUnmount() {
window.removeEventListener("resize", this.onSize)
}
clearEchart = () => {
if (this.chart) {
this.chart.dispose();
}
};
getOption = (xAxis, datas) => {
const { unit } = this.props
let option = {
title: {
text: '成本分析'
},
legend: {},
grid: {
left: '3%',
right: '10%',
bottom: '0%',
containLabel: true
},
xAxis: {
type: 'category',
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
},
yAxis: {
type: 'value',
name: '单位:万元',
},
tooltip: {},
series: [
{
data: [120, 200, 150, 80, 70, 110, 130],
type: 'bar'
}
]
}
return option;
};
render() {
const { domId, width, height } = this.props;
return <div id={domId} style={{ height: height, width: width || '100%', margin: '0px auto' }} />;
}
}
export default ColumnChart;

107
web/client/src/sections/shouye/components/charts/stackColumn.js

@ -0,0 +1,107 @@
import React, { Component } from 'react';
import * as echarts from 'echarts';
class StackColumn extends Component {
constructor(props) {
super(props);
this.state = {
};
}
componentDidMount() {
const { xAxis, datas, domId } = this.props;
this.createCharts(xAxis, datas, domId);
}
componentWillReceiveProps(nextProps) {
let { xAxis, datas, domId } = nextProps;
if (JSON.stringify(xAxis) != JSON.stringify(this.props.xAxis) || JSON.stringify(datas) != JSON.stringify(this.props.datas)) {
this.createCharts(xAxis, datas, domId);
}
}
createCharts = (xAxis, datas, domId) => {
this.clearEchart();
let chartDom = document.getElementById(domId);
this.chart = echarts.init(chartDom);
let option = this.getOption(xAxis, datas);
this.chart.setOption(option);
this.onSize = () => {
this.chart.resize();
}
window.addEventListener("resize", this.onSize);
};
// 组件销毁删除监听
componentWillUnmount() {
window.removeEventListener("resize", this.onSize)
}
clearEchart = () => {
if (this.chart) {
this.chart.dispose();
}
};
getOption = (xAxis, datas) => {
let xAxisData = [];
let data1 = [];
let data2 = [];
for (let i = 0; i < 10; i++) {
xAxisData.push('Class' + i);
data1.push(+(Math.random() * 2).toFixed(2));
data2.push(+(Math.random() * 5).toFixed(2));
}
let emphasisStyle = {
itemStyle: {
shadowBlur: 10,
shadowColor: 'rgba(0,0,0,0.3)'
}
};
let option = {
title: {
text: '设备维修分析'
},
legend: {
data: ['异常数', '维修数'],
left: '40%'
},
tooltip: {},
xAxis: {
data: xAxisData,
axisLine: { onZero: true },
splitLine: { show: false },
splitArea: { show: false }
},
yAxis: {
name: '单位:次数',
},
grid: {
left: '3%',
right: '10%',
bottom: '0%',
containLabel: true
},
series: [
{
name: '异常数',
type: 'bar',
stack: 'one',
emphasis: emphasisStyle,
data: data1
},
{
name: '维修数',
type: 'bar',
stack: 'one',
emphasis: emphasisStyle,
data: data2
}
]
}
return option;
};
render() {
const { domId, width, height } = this.props;
return <div id={domId} style={{ height: height, width: width || '100%', margin: '0px auto' }} />;
}
}
export default StackColumn;

85
web/client/src/sections/shouye/components/charts/xColumn.js

@ -0,0 +1,85 @@
import React, { Component } from 'react';
import * as echarts from 'echarts';
class XColumn extends Component {
constructor(props) {
super(props);
this.state = {
};
}
componentDidMount() {
const { xAxis, yAxis, domId } = this.props;
this.createCharts(xAxis, yAxis, domId);
}
componentWillReceiveProps(nextProps) {
let { xAxis, yAxis, domId } = nextProps;
if (JSON.stringify(xAxis) != JSON.stringify(this.props.xAxis) || JSON.stringify(yAxis) != JSON.stringify(this.props.yAxis)) {
this.createCharts(xAxis, yAxis, domId);
}
}
createCharts = (xAxis, yAxis, domId) => {
this.clearEchart();
let chartDom = document.getElementById(domId);
this.chart = echarts.init(chartDom);
let option = this.getOption(xAxis, yAxis);
this.chart.setOption(option);
this.onSize = () => {
this.chart.resize();
}
window.addEventListener("resize", this.onSize);
};
// 组件销毁删除监听
componentWillUnmount() {
window.removeEventListener("resize", this.onSize)
}
clearEchart = () => {
if (this.chart) {
this.chart.dispose();
}
};
getOption = (xAxis, yAxis) => {
let option = {
title: {
text: '故障点位分析'
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow'
}
},
legend: {},
grid: {
left: '3%',
right: '10%',
bottom: '0%',
containLabel: true
},
xAxis: {
type: 'value',
boundaryGap: [0, 0.01]
},
yAxis: {
type: 'category',
data: yAxis
},
series: [
{
name: '异常数',
type: 'bar',
data: xAxis
}
]
};
return option;
};
render() {
const { domId, width, height } = this.props;
return <div id={domId} style={{ height: height, width: width || '100%', margin: '0px auto' }} />;
}
}
export default XColumn;

158
web/client/src/sections/shouye/containers/shouye.js

@ -5,89 +5,135 @@ import moment from "moment";
import '../style.less';
import { push } from 'react-router-redux';
import { Model } from 'echarts';
import {getPatrolPlan} from '../../patrolManage/actions/plan'
import { getPatrolPlan } from '../../patrolManage/actions/plan'
import XColumn from '../components/charts/xColumn'
import StackColumn from '../components/charts/stackColumn'
import AlarmStatistics from '../components/alarm/alarmStatistics'
import Column from '../components/charts/column'
const Information = (props) => {
const { dispatch, actions, user, loading } = props
const { dispatch, actions, user, loading, clientHeight } = props
const { patrolManage, issueHandle } = actions
const [planedata,setplandata] = useState([])
const [xunjiandata,setxunjiandata] = useState([])
const [shijiandata,setshijiandata] = useState([])
const topdata =[]
const [planedata, setplandata] = useState([])
const [xunjiandata, setxunjiandata] = useState([])
const [shijiandata, setshijiandata] = useState([])
const [chartData1, setChartData1] = useState([])
const [chartData2, setChartData2] = useState([])
const [chartData3, setChartData3] = useState([])
const [chartData4, setChartData4] = useState([])
const topdata = []
const format = 'YYYY-MM-DD HH:mm:ss'
const times = [moment().subtract(70, 'years').format(format), moment().format(format)]
useEffect(()=>{
dispatch(getPatrolPlan()).then(async (res)=>{
const res2 = await dispatch(patrolManage.records(`patrolRecord/all/${times[0]}/${times[1]}/null/null`))
console.log(res2,'res2')
setshijiandata(res2?.payload?.data)
setxunjiandata(res2?.payload?.data.filter(i=>parseInt(moment().format('YYYYMMDD'))=== parseInt(moment(i.inspectionTime ).format('YYYYMMDD'))))
const count = res?.payload?.data?.rows?.filter(i=>{
// console.log(i?.frequency?.match(/^[0-9]*$/),'jjj')
if(i?.frequency.split('/')[i?.frequency.split('/').length-1]==='天'){
// console.log(i?.frequency?.match(/[\d.]/g).join(''),'jjj')
return parseInt(moment().format('YYYYMMDD'))<=parseInt(moment(i.endTime).format('YYYYMMDD'))
// console.log('是的',i?.frequency.split('/')[i?.frequency.split('/').length-1])
}else if(i?.frequency.split('/')[i?.frequency.split('/').length-1]==='周'){
// console.log(i?.frequency?.match(/^[0-9]*$/),'jjj')
return parseInt(moment().format('YYYYMMDD'))<=parseInt(moment(i.endTime).format('YYYYMMDD'))&&res2?.payload?.data?.filter(j=>j.patrolPlanId===i.id
&&moment(j.inspectionTim).week()===moment().week()).length<parseInt(i?.frequency?.match(/[\d.]/g).join(''))
useEffect(() => {
dispatch(getPatrolPlan()).then(async (res) => {
const res2 = await dispatch(patrolManage.records(`patrolRecord/all/${times[0]}/${times[1]}/null/null`))
setshijiandata(res2?.payload?.data)
setxunjiandata(res2?.payload?.data.filter(i => parseInt(moment().format('YYYYMMDD')) === parseInt(moment(i.inspectionTime).format('YYYYMMDD'))))
const count = res?.payload?.data?.rows?.filter(i => {
if (i?.frequency.split('/')[i?.frequency.split('/').length - 1] === '天') {
return parseInt(moment().format('YYYYMMDD')) <= parseInt(moment(i.endTime).format('YYYYMMDD'))
} else if (i?.frequency.split('/')[i?.frequency.split('/').length - 1] === '周') {
return parseInt(moment().format('YYYYMMDD')) <= parseInt(moment(i.endTime).format('YYYYMMDD')) && res2?.payload?.data?.filter(j => j.patrolPlanId === i.id
&& moment(j.inspectionTim).week() === moment().week()).length < parseInt(i?.frequency?.match(/[\d.]/g).join(''))
}
else if(i?.frequency.split('/')[i?.frequency.split('/').length-1]==='月'){
// console.log(i?.frequency?.match(/^[0-9]*$/),'jjj')
return parseInt(moment().format('YYYYMMDD'))<=parseInt(moment(i.endTime).format('YYYYMMDD'))&&res2?.payload?.data?.filter(j=>j.patrolPlanId===i.id
&&moment(j.inspectionTim).month()===moment().month()).length<parseInt(i?.frequency?.match(/[\d.]/g).join(''))
else if (i?.frequency.split('/')[i?.frequency.split('/').length - 1] === '月') {
return parseInt(moment().format('YYYYMMDD')) <= parseInt(moment(i.endTime).format('YYYYMMDD')) && res2?.payload?.data?.filter(j => j.patrolPlanId === i.id
&& moment(j.inspectionTim).month() === moment().month()).length < parseInt(i?.frequency?.match(/[\d.]/g).join(''))
}
})
console.log(count,'count')
setplandata(count)
console.log(res,'res')
calcChartData(res2?.payload?.data)
})
}, [])
const calcChartData = (data) => {
let arr = []
data.filter(d => d.alarm).forEach(l => {
let ext = arr.find(a => a.name === l.point.name);
if (ext) {
ext.value++;
} else {
arr.push({ name: l.point.name, value: 1 })
}
})
},[])
console.log(xunjiandata,'xunjiandata')
arr.sort((a, b) => b.value - a.value)
setChartData1(arr.slice(0, 10));//展示前10名
}
return (
<>
<div className='shouyetop'>
<div className='shouyetopitem'>
<div className='shouyetopitem-left' >
<div>今日巡检</div>
<div>{planedata.length}</div>
<div className='shouyetop'>
<div className='shouyetopitem'>
<div className='shouyetopitem-left' >
<div>今日巡检</div>
<div>{planedata.length}</div>
</div>
<div className='shouyetopitem-right'>
<div>完成巡检{xunjiandata.length}</div>
<div>巡检上报{xunjiandata.filter(i => i?.alarm === true).length}</div>
</div>
</div>
<div className='shouyetopitem-right'>
<div>完成巡检{xunjiandata.length}</div>
<div>巡检上报{xunjiandata.filter(i=>i?.alarm===true).length}</div>
<div className='shouyetopitem'>
<div className='shouyetopitem-left' >
<div>今日事件</div>
<div>{xunjiandata.filter(i => i?.alarm === true).length}</div>
</div>
<div className='shouyetopitem-right'>
<div>已处理</div>
<div>未处理2</div>
</div>
</div>
</div>
<div className='shouyetopitem'>
<div className='shouyetopitem-left' >
<div>今日事件</div>
<div>{xunjiandata.filter(i=>i?.alarm===true).length}</div>
</div>
<div className='shouyetopitem-right'>
<div>已处理</div>
<div>未处理2</div>
<div className='shouyetopitem'>
<div className='shouyetopitem-left' >
<div>今日预警</div>
<div>0</div>
</div>
<div className='shouyetopitem-right'>
<div>已下发2</div>
</div>
</div>
</div>
<div className='shouyetopitem'>
<div className='shouyetopitem-left' >
<div>今日预警</div>
<div>0</div>
<Card className='shouye-chart-card'>
<div style={{ display: 'flex', justifyContent: 'space-between' }}>
<div style={{ width: '45%' }}>
<XColumn
domId={'column-chart-1'}
height={clientHeight * 0.35}
xAxis={chartData1.map(cd => cd.value).reverse()}
yAxis={chartData1.map(cd => cd.name).reverse()} />
</div>
<div style={{ width: '45%' }}>
<StackColumn
domId={'column-chart-2'}
height={clientHeight * 0.35} />
</div>
</div>
<div className='shouyetopitem-right'>
<div>已下发2</div>
<div style={{ display: 'flex', justifyContent: 'space-between' }}>
<div style={{ width: '45%' }}>
<AlarmStatistics height={clientHeight * 0.25} />
</div>
<div style={{ width: '45%' }}>
<Column
domId={'column-chart-3'}
height={clientHeight * 0.35} />
</div>
</div>
</div>
</div>
</Card>
</>
)
}
function mapStateToProps (state) {
function mapStateToProps(state) {
const { auth, global } = state;
return {
user: auth.user,
actions: global.actions,
clientHeight: global.clientHeight
};
}

16
web/client/src/sections/shouye/style.less

@ -26,3 +26,19 @@
}
}
}
.shouye-chart-card {
margin: 0 1.875rem;
margin-top: 20px;
}
.alarm-row {
background-repeat: no-repeat;
background-size: 100% 100%;
padding: 0px 14px 0px 8px;
color: #fff;
}
.rank1 {
background-image: url('/assets/images/homePage/rank1.png');
}
.rank2 {
background-image: url('/assets/images/homePage/rank2.png');
}
Loading…
Cancel
Save