diff --git a/src/layout/FullScreenInter.js b/src/layout/FullScreenInter.js index 8423e86..cbf1429 100644 --- a/src/layout/FullScreenInter.js +++ b/src/layout/FullScreenInter.js @@ -44,259 +44,15 @@ class FullScreen extends React.Component { sliderSize: '24px', nowDate: '', riskTypeRate: [], //风险等级占比 + linkSum: [], jobTodayTop3: [], //当日工作票排名前三 - hiddenRectifyRate: {}, //隐患整改率 + hiddenRectify: {}, //隐患整改率 taskTop3: [], //各事项排名前三 jobFinishRate: [], //作业现场完成情况统计 safeCheckSum: [], //各公司安全检查统计 - riskChangeData: [ - { name: '隐患数量', value: 103 }, - { name: '延期整改数', value: 18 }, - { name: '按期整改数', value: 85 }, - ], - configBanner: [ - { name: '首页', value: 103 }, - { name: '风险管控', value: 103 }, - { name: '隐患治理', value: 103 }, - { name: '班组建设', value: 103 }, - { name: '危险作业', value: 103 }, - { name: '安全培训', value: 103 }, - ], - checkData: [ - { name: '公司检查', value: 103 }, - { name: '部门检查', value: 79 }, - { name: '车间检查', value: 86 }, - { name: '班组检查', value: 94 }, - ], - widthp: '70%', - scrollConfig: { - header: ['检查类型', '检查次数', '完成率'], - data: [ - ['巡回检查', '322', '99%'], - ['例行检查', '255', '99%'], - ['日常检查', '253', '99%'], - ['专业检查', '123', '99%'], - ['巡回检查', '322', '99%'], - ['例行检查', '255', '99%'], - ['日常检查', '253', '99%'], - ['专业检查', '123', '99%'], - ], - waitTime: 200000, - }, - safescrollConfig: { - header: ['部门', '车间', '活动', '进度'], - data: [ - ['矿山部', '穿爆车间', '班前会议', '98%'], - ['矿山部', '金宇宁化分公司', '班前会议', '98%'], - ['选矿部', '破碎车间', '班前会议', '95%'], - ['矿山部', '磨重车间', '班前会议', '92%'], - ['矿山部', '机电设备管理科', '班前会议', '83%'], - ['矿山部', '钨细泥回收车间', '班前会议', '93%'], - ['矿山部', '穿爆车间', '班前会议', '90%'], - ['矿山部', '穿爆车间', '班前会议', '90%'], - ['矿山部', '穿爆车间', '班前会议', '90%'], - ], - index: true, - columnWidth: [80, 200, 300, 200, 200], - align: ['center'], - waitTime: 2000, - }, - chartConfig: { - data: [ - { - name: '电工日常班', - value: 97, - }, - { - name: '电工三班', - value: 95, - }, - { - name: '破碎一班', - value: 91, - }, - { - name: '磨重二班', - value: 86, - }, - { - name: '磨重三班', - value: 83, - }, - { - name: '电工日常班', - value: 97, - }, - { - name: '电工三班', - value: 95, - }, - { - name: '破碎一班', - value: 91, - }, - { - name: '磨重二班', - value: 86, - }, - { - name: '磨重三班', - value: 83, - }, - { - name: '电工日常班', - value: 97, - }, - { - name: '电工三班', - value: 95, - }, - { - name: '破碎一班', - value: 91, - }, - { - name: '磨重二班', - value: 86, - }, - { - name: '磨重三班', - value: 83, - }, - ], - showValue: true, - }, - riskData: [ - { color: '#c92a2a', value: 2, name: '重大风险' }, - { color: '#FF6710', value: 5, name: '较大风险' }, - { color: '#FFDD1E', value: 15, name: '一般风险' }, - { color: '#0091FF', value: 30, name: '低风险' }, - ], - WaterLevelPondconfig1: { - data: [75], - shape: 'round', - }, - WaterLevelPondconfig2: { - data: [85], - shape: 'round', - }, - WaterLevelPondconfig3: { - data: [95], - shape: 'round', - }, - completeData: [ - { - name: '班组会议完成率', - value: 75, - }, - { - name: '岗位交接班完成率', - value: 85, - }, - { - name: '岗位当班记录完成率', - value: 95, - }, - ], - // completeDatatwo: { - // name: "岗位交接班完成率", - // value: 85, - // id: "completetwo", - // }, - // completeDatathree: { - // name: "岗位当班记录完成率", - // value: 95, - // id: "completethree", - // }, - meetingData: [ - { - name: '班前会议', - value: 32, - }, - { - name: '班组活动', - value: 132, - }, - { - name: '岗位交接班', - value: 32, - }, - { - name: '岗位当班', - value: 132, - }, - { - name: '班前会议', - value: 32, - }, - { - name: '班组活动', - value: 132, - }, - { - name: '岗位交接班', - value: 32, - }, - { - name: '岗位当班', - value: 132, - }, - ], - roaData: [ - { - name: '总任务数', - value: 1456, - }, - { - name: '超时待办数', - value: 132, - }, - { - name: '安全检查数', - value: 1456, - }, - { - name: '检查完成率', - value: 32, - }, - { - name: '职业危害', - value: 132, - }, - { - name: '管控措施', - value: 1456, - }, - { - name: '安全检查库', - value: 132, - }, - { - name: '危险源库', - value: 32, - }, - { - name: '培训计划完成率', - value: 132, - }, - { - name: '用户活跃度', - value: 1456, - }, - { - name: '系统用户数', - value: 132, - }, - { - name: '正常已办数', - value: 32, - }, - { - name: '未完成数', - value: 132, - }, - ], + listSETrainSum: [], //各公司安全培训统计 scale: getScale(), + configBanner: ['首页', '风险管理', '安全检查', '隐患管理', '作业现场', '安全培训'], }; this.echartsInstances = { riskLevel: null, @@ -317,100 +73,33 @@ class FullScreen extends React.Component { // this.getHomeTitle(); this.getHomeDataArray(); this.setState({ activeTab: '首页' }); - this.riskLevel(); - this.safedanger(); - this.completeChart(this.state.completeData); + this.timer = setInterval(() => { this.setState({ nowDate: this.getDate(), }); }, 1000); } + executionChart = () => { + this.riskLevel(); + this.safeCheckChart(); + this.dangerOperation(); + this.completeChart(); + this.backLog(); + this.safedanger(); + }; componentDidUpdate(prevProps, prevState) { // 当从其他tab切换回首页时 if (prevState.activeTab !== this.state.activeTab && this.state.activeTab === '首页') { - console.log('切换到首页,初始化图表'); - // 延迟确保DOM已渲染 setTimeout(() => { - this.riskLevel(); - this.safedanger(); - this.completeChart(this.state.completeData); + this.executionChart(); }, 300); // 稍微增加延迟时间 } - - // 当离开首页时,清理图表 - if (prevState.activeTab === '首页' && this.state.activeTab !== '首页') { - console.log('离开首页,清理图表'); - this.cleanupCharts(); - } } - getHomeDataArray = () => { - var orgId = storage('lacal').getItem('webOrgId')?.val; //登录后有存储登录信息 - let json = initFilter(orgId); - this.props.dispatch({ - type: 'app/getDataByPost', - payload: json, - url: 'BI/BIKanBanController/ReturnAllData', - onComplete: (ret) => { - console.log(ret, '877777'); - if (ret) { - console.log('首页标题数据', ret); - this.setState({ - riskTypeRate: ret.riskTypeRate, - jobTodayTop3: ret.jobTodayTop3, - hiddenRectifyRate: ret.hiddenRectifyRate, - taskTop3: ret.taskTop3, - jobFinishRate: ret.jobFinishRate, - safeCheckSum: ret.safeCheckSum, - }); - } - }, - }); - }; - - // 添加清理方法 - cleanupCharts = () => { - // 清理风险分级图表 - if (this.echartsInstances.riskLevel) { - this.echartsInstances.riskLevel.dispose(); - this.echartsInstances.riskLevel = null; - } - - // 清理运行走势图 - if (this.echartsInstances.opretionTrend) { - this.echartsInstances.opretionTrend.dispose(); - this.echartsInstances.opretionTrend = null; - } - - // 清理完成率图表 - if (this.echartsInstances.completeone) { - this.echartsInstances.completeone.dispose(); - this.echartsInstances.completeone = null; - } - - // 移除resize监听器 - if (this.riskResizeHandler) { - window.removeEventListener('resize', this.riskResizeHandler); - this.riskResizeHandler = null; - } - - if (this.trendResizeHandler) { - window.removeEventListener('resize', this.trendResizeHandler); - this.trendResizeHandler = null; - } - - if (this.completeResizeHandler) { - window.removeEventListener('resize', this.completeResizeHandler); - this.completeResizeHandler = null; - } - }; handleTabClick = (name) => { // 如果从首页切换到其他tab,先清理图表 - if (this.state.activeTab === '首页' && name !== '首页') { - this.cleanupCharts(); - } this.setState({ activeTab: name }); @@ -435,35 +124,7 @@ class FullScreen extends React.Component { componentWillUnmount() { window.removeEventListener('resize', this.setScale); clearInterval(this.timer); - this.cleanupCharts(); } - getHomeTitle = () => { - console.log('获取首页标题数据'); - var orgId = storage('lacal').getItem('webOrgId')?.val; //登录后有存储登录信息 - let json = initFilter(orgId); - console.log(json, '首页标题数据'); - this.props.dispatch({ - type: 'app/getDataByPost', - payload: json, - url: 'PF/HomeTitle/OrderPaged', - onComplete: (ret) => { - console.log(ret, '877777'); - if (ret) { - console.log('首页标题数据', ret); - this.setState({ - safetySloganOne: ret[0].TITLE, - // safetySloganOne: "1.安全方针:以人为本、关注健康、依法治企、安全发展。 2.安全理念:一切风险皆可控,一切事故皆可防!3.安全方针:以人为本、关注健康、依法治企、安全发展。4.安全方针:以人为本、关注健康、依法治企、安全发展。5.安全方针:以人为本、关注健康、依法治企、安全发展。 6.安全理念:一切风险皆可控,一切事故皆可防!7.安全方针:以人为本、关注健康、依法治企、安全发展。8.安全方针:以人为本、关注健康、依法治企、安全发展。", - animationDuration: ret[0].SECOND, - sliderColor: ret[0].COCOR, - sliderSize: ret[0].FONTSIZE, - }); - } - }, - }); - }; - callback = (key) => { - console.log(key); - }; getDate = () => { var myDate = new Date(); var year = myDate.getFullYear(); //获取当前年 @@ -491,357 +152,33 @@ class FullScreen extends React.Component { var now = year + ' 年 ' + mon + ' 月 ' + date + ' 日 ' + '\t\t\t' + hours + ' : ' + minutes + ' : ' + seconds; return now; }; - completeChart = (evt) => { - if (this.echartsInstances.completeone) { - this.echartsInstances.completeone.dispose(); - this.echartsInstances.completeone = null; - } - - let completeCharts = document.getElementById('completeone'); - if (!completeCharts) { - requestAnimationFrame(() => { - this.completeChart(evt); - }); - return; - } - - console.log('初始化完成率图表'); - - this.echartsInstances.completeone = echarts.init(completeCharts); - let seriesArr = []; - let centerArr = [ - ['20%', '50%'], - ['50%', '50%'], - ['80%', '50%'], - ]; - evt.forEach((item, index) => { - seriesArr.push({ - center: centerArr[index], - axisLine: { - show: true, - lineStyle: { - color: [ - [0.25, '#c23531'], - [0.5, '#EFC631'], - [0.75, '#63869e'], - [1, '#91c7ae'], - ], - width: 8, - }, - radius: '90%', // 控制轴线本身的半径 - }, - axisTick: { - show: false, - }, - splitLine: { - length: 8, // 刻度线长度 - distance: 25, // 向内移动距离,负值越大越向内 - lineStyle: { - color: '#fff', // 刻度线颜色 - width: 2, // 刻度线宽度 - }, - }, - axisLabel: { - distance: 15, // 标签与刻度线的距离 - textStyle: { - color: '#fff', - fontSize: 10, - }, - // 调整标签偏移 - offset: [0, 0], // [水平偏移, 垂直偏移] - }, - itemStyle: { - normal: { - color: 'auto', - }, - }, - radius: '80%', - pointer: { - show: true, - width: '8%', - length: '20%', - }, - title: { - textStyle: { - // fontWeight: 'bolder', - fontSize: 14, - color: '#fff', - }, - offsetCenter: [0, '100%'], - }, - detail: { - textStyle: { - fontWeight: 'bolder', - fontSize: 20, - color: '#fff', - }, - offsetCenter: [0, '68%'], - // formatter: '{value}万\n(5048人)', - }, - min: 0, - max: 100, - // name: '米类仪表盘', - type: 'gauge', - show: false, - splitNumber: 10, - data: [ - { - name: item.name, - value: item.value, - }, - ], - }); + getHomeDataArray = () => { + var orgId = storage('lacal').getItem('webOrgId')?.val; //登录后有存储登录信息 + let json = initFilter(orgId); + this.props.dispatch({ + type: 'app/getDataByPost', + payload: json, + url: 'BI/BIKanBanController/ReturnAllData', + onComplete: (ret) => { + if (ret) { + this.setState( + { + riskTypeRate: ret.riskTypeRate, + linkSum: ret.linkSum, + jobTodayTop3: ret.jobTodayTop3, + hiddenRectify: ret.hiddenRectify, + taskTop3: ret.taskTop3, + jobFinishRate: ret.jobFinishRate, + safeCheckSum: ret.safeCheckSum, + listSETrainSum: ret.listSETrainSum, + }, + () => { + this.executionChart(); + } + ); + } + }, }); - this.echartsInstances.completeone.setOption({ - series: seriesArr, - }); - - // 监听resize - const resizeHandler = () => { - if (this.echartsInstances.completeone) { - this.echartsInstances.completeone.resize(); - } - }; - - if (this.completeResizeHandler) { - window.removeEventListener('resize', this.completeResizeHandler); - } - - this.completeResizeHandler = resizeHandler; - window.addEventListener('resize', resizeHandler); - }; - safedanger = () => { - if (this.echartsInstances.opretionTrend) { - this.echartsInstances.opretionTrend.dispose(); - this.echartsInstances.opretionTrend = null; - } - - const opretionTrends = document.getElementById('opretionTrend'); - if (!opretionTrends) { - requestAnimationFrame(() => { - this.safedanger(); - }); - return; - } - - console.log('初始化运行走势图'); - this.echartsInstances.opretionTrend = echarts.init(opretionTrends); - - // ... 原有配置代码 - let bgColor = '#000'; - let color = [ - '#0090FF', - '#36CE9E', - '#e690d1', - '#FF515A', - '#8B5CFF', - '#00CA69', - '#FFC107', - '#E91E63', - '#9C27B0', - '#3F51B5', - '#2196F3', - '#4CAF50', - '#FF9800', - '#795548', - '#607D8B', - ]; - const seriesNames = [ - '选矿部门', - '矿山部门', - '尾矿部门', - '机电部门', - '安全部门', - '生产部门', - '技术部门', - '维修部门', - '运输部门', - '仓储部门', - '质检部门', - '环保部门', - '研发部门', - '行政部门', - '财务部门', - ]; - // 生成x轴数据(12个月) - let xAxisData = []; - for (let i = 1; i <= 12; i++) { - xAxisData.push(i.toString()); - } - - // 生成15个系列的数据 - let seriesArr = []; - for (let i = 0; i < 15; i++) { - let yAxisData = []; - for (let j = 0; j < 12; j++) { - // 生成60-100的随机数据 - yAxisData.push(Math.floor(Math.random() * 40) + 60); - } - - seriesArr.push({ - name: seriesNames[i], - type: 'line', - smooth: true, - symbolSize: 6, - data: yAxisData, - }); - } - - const hexToRgba = (hex, opacity) => { - let rgbaColor = ''; - let reg = /^#[\da-f]{6}$/i; - if (reg.test(hex)) { - rgbaColor = `rgba(${parseInt('0x' + hex.slice(1, 3))},${parseInt('0x' + hex.slice(3, 5))},${parseInt( - '0x' + hex.slice(5, 7) - )},${opacity})`; - } - return rgbaColor; - }; - const option = { - title: [ - { - text: '各家公司的安全教育培训学时统计', - x: 'center', - y: '5%', - textStyle: { - fontSize: 16, - color: '#fff', - }, - }, - ], - backgroundColor: '', - color: color, - legend: { - type: 'scroll', // 如果项目多可以使用滚动 - orient: 'vertical', // 设置为垂直排列 - right: 10, // 距离右侧的距离 - top: 'center', // 垂直居中 - align: 'left', // 文本左对齐 - textStyle: { - color: '#fff', // 文字颜色 - fontSize: 12, - }, - itemStyle: { - color: 'inherit', - borderWidth: 0, - opacity: 1, - }, - symbol: 'rect', // 实心矩形 - symbolSize: [12, 8], // 大小 - itemWidth: 10, // 图例标记的宽度 - itemHeight: 10, // 图例标记的高度 - itemGap: 15, // 图例每项之间的间隔 - pageButtonItemGap: 3, - pageButtonGap: 5, - pageButtonPosition: 'end', - pageIconColor: '#00caf7', - width: 100, // 限制宽度 - height: 250, // 限制高度,超出就会显示滚动 - }, - tooltip: { - trigger: 'axis', - formatter: function (params) { - let html = ''; - params.forEach((v) => { - html += `
- - ${v.seriesName} - ${v.value} - %`; - }); - - return html; - }, - extraCssText: 'background: #fff; border-radius: 0;box-shadow: 0 0 3px rgba(0, 0, 0, 0.2);color: #333;', - axisPointer: { - type: 'shadow', - shadowStyle: { - // color: "#ffffff", - shadowColor: 'rgba(225,225,225,1)', - shadowBlur: 5, - }, - }, - }, - grid: { - top: '15%', - left: '5%', - right: '15%', // 为图例留出空间 - bottom: '15%', - containLabel: true, - }, - xAxis: [ - { - type: 'category', - boundaryGap: false, - axisLabel: { - formatter: '{value}月', - textStyle: { - color: '#fff', - }, - }, - axisTick: { - show: false, - }, - axisLine: { - lineStyle: { - color: '#fff', - }, - }, - data: xAxisData, - }, - ], - yAxis: [ - { - type: 'value', - axisLabel: { - textStyle: { - color: '#fff', - }, - }, - nameTextStyle: { - color: '#fff', - fontSize: 12, - lineHeight: 40, - }, - splitLine: { - show: false, - lineStyle: { - type: 'dashed', - color: '#fff', - }, - }, - axisLine: { - show: false, - lineStyle: { - color: '#00c7ff', - width: 1, - type: 'solid', - }, - }, - axisTick: { - show: false, - }, - }, - ], - series: seriesArr, - }; - - this.echartsInstances.opretionTrend.setOption(option); - // 监听resize - const resizeHandler = () => { - if (this.echartsInstances.opretionTrend) { - this.echartsInstances.opretionTrend.resize(); - } - }; - - if (this.trendResizeHandler) { - window.removeEventListener('resize', this.trendResizeHandler); - } - - this.trendResizeHandler = resizeHandler; - window.addEventListener('resize', resizeHandler); }; riskLevel = () => { // 如果已有实例,先销毁 @@ -852,16 +189,12 @@ class FullScreen extends React.Component { const riskLevels = document.getElementById('riskLevelFull'); if (!riskLevels) { - console.warn('风险分级图表容器未找到'); // 使用requestAnimationFrame而不是setTimeout requestAnimationFrame(() => { - this.riskLevel(); + this.executionChart(); }); return; } - - console.log('初始化风险分级图表'); - // 初始化echarts实例并保存引用 this.echartsInstances.riskLevel = echarts.init(riskLevels); const option = { @@ -945,7 +278,10 @@ class FullScreen extends React.Component { show: false, }, }, - data: this.state.riskTypeRate, + data: this.state.riskTypeRate.map((item) => ({ + name: item.riskType, + value: item.count, + })), }, ], }; @@ -967,6 +303,849 @@ class FullScreen extends React.Component { this.riskResizeHandler = resizeHandler; window.addEventListener('resize', resizeHandler); }; + transformDat = (originalData, barTopColor, num) => { + // 添加空值检查 + if (!originalData || !Array.isArray(originalData) || originalData.length === 0) { + return { + companyNames: [], + series: [], + legendData: [], + }; + } + // 获取所有的类型名称(去重) + let allTypes = []; + if (num == 1) { + allTypes = [...new Set(originalData.flatMap((item) => item.details?.map((detail) => detail.jobName)))]; + } else { + allTypes = [...new Set(originalData.flatMap((item) => item.details?.map((detail) => detail.name)))]; + } + + // 获取所有的公司名称(作为 x 轴标签) + const companyNames = originalData?.map((item) => item.company); + + // 为每个类型创建数据系列 + const series = allTypes?.map((typeName, index) => { + return { + name: typeName, + type: 'bar', + itemStyle: { + normal: { + color: function (params) { + if (num == 1) { + return barTopColor[index]; + } else { + return new echarts.graphic.LinearGradient(0, 0, 0, 1, [ + { + offset: 0, + color: barTopColor[index][0], + }, + { + offset: 1, + color: barTopColor[index][1], + }, + ]); + } + }, + }, + }, + data: originalData?.map((company) => { + // 找到该公司对应类型的数据,如果没有则返回 0 + const detail = company.details?.find((d) => (num == 1 ? d.jobName : d.name) === typeName); + return detail ? detail.qty : 0; + }), + }; + }); + + return { + companyNames, // x 轴数据 + series, // 系列数据 + legendData: allTypes, // legend 的 data + }; + }; + + safeCheckChart = () => { + if (this.echartsInstances.safeCheckChart) { + this.echartsInstances.safeCheckChart.dispose(); + this.echartsInstances.safeCheckChart = null; + } + + let safeCheckCharts = document.getElementById('safeCheckChart'); + if (!safeCheckCharts) { + requestAnimationFrame(() => { + this.safeCheckChart(); + }); + return; + } + const barTopColor = ['#02c3f1', '#53e568', '#a154e9']; + + this.echartsInstances.safeCheckChart = echarts.init(safeCheckCharts); + let xdata = []; + xdata = this.transformDat(this.state.jobTodayTop3, barTopColor, 1); + this.echartsInstances.safeCheckChart.setOption({ + title: { + text: '当日工作票排名前三家的数据', + textStyle: { + fontSize: 16, + color: '#fff', + }, + }, + tooltip: { + trigger: 'axis', + axisPointer: { + // 坐标轴指示器,坐标轴触发有效 + type: 'shadow', // 默认为直线,可选为:'line' | 'shadow' + }, + }, + legend: { + data: xdata.legendData, + align: 'right', + right: 10, + itemGap: 16, + itemWidth: 18, + itemHeight: 10, + textStyle: { + color: '#fff', + fontStyle: 'normal', + fontFamily: '微软雅黑', + fontSize: 14, + }, + }, + color: barTopColor, + grid: { + left: '3%', + right: '4%', + bottom: '3%', + containLabel: true, + }, + xAxis: [ + { + type: 'category', + data: xdata.companyNames, + textStyle: { + fontSize: 18, + color: '#ffffff', + }, + //坐标轴 + axisLine: { + lineStyle: { + color: '#3eb2e8', + }, + }, + //坐标值标注 + axisLabel: { + show: true, + textStyle: { + color: '#fff', + }, + }, + }, + ], + yAxis: [ + { + type: 'value', + textStyle: { + fontSize: 14, + color: '#ffffff', + }, + //坐标轴 + axisLine: { + show: false, + }, + //坐标值标注 + axisLabel: { + show: true, + textStyle: { + color: '#fff', + }, + }, + //分格线 + splitLine: { + lineStyle: { + color: '#4784e8', + }, + }, + }, + ], + series: xdata.series, + }); + + // 监听resize + const resizeHandler = () => { + if (this.echartsInstances.safeCheckChart) { + this.echartsInstances.safeCheckChart.resize(); + } + }; + + if (this.safeCheckResizeHandler) { + window.removeEventListener('resize', this.safeCheckResizeHandler); + } + + this.safeCheckResizeHandler = resizeHandler; + window.addEventListener('resize', resizeHandler); + }; + dangerOperation = () => { + // 如果已有实例,先销毁 + if (this.echartsInstances.dangerOperation) { + this.echartsInstances.dangerOperation.dispose(); + this.echartsInstances.dangerOperation = null; + } + + const dangerOperationCharts = document.getElementById('dangerOperationChart'); + if (!dangerOperationCharts) { + // 使用requestAnimationFrame而不是setTimeout + requestAnimationFrame(() => { + this.executionChart(); + }); + return; + } + + let legendData = []; + (this.state.linkSum.map((item) => { + legendData.push(item.name); + }), + // 初始化echarts实例并保存引用 + (this.echartsInstances.dangerOperation = echarts.init(dangerOperationCharts))); + + const option = { + color: [ + '#0090FF', + '#36CE9E', + '#e690d1', + '#FF515A', + '#8B5CFF', + '#00CA69', + '#FFC107', + '#E91E63', + '#9C27B0', + '#3F51B5', + '#2196F3', + '#4CAF50', + '#FF9800', + '#795548', + '#607D8B', + ], + title: [ + { + text: '各公司危险作业分类统计', + x: 'center', + y: '5%', + textStyle: { + fontSize: 16, + color: '#fff', + }, + }, + ], + legend: { + type: 'scroll', + orient: 'vertical', + left: '5%', + align: 'left', + top: '5%', + textStyle: { + color: '#fff', + }, + height: 250, + }, + tooltip: { + trigger: 'item', + formatter: function (params) { + const color = params.color; + return `
+ + ${params.name}: + ${params.value} +
`; + }, + backgroundColor: 'rgba(255, 255, 255, 0.5)', + borderColor: '#FFFFFF', + borderWidth: 2, + textStyle: { + color: '#000', + fontSize: 14, + fontWeight: 'normal', + }, + }, + series: [ + { + name: '访问来源', + type: 'pie', + minAngle: 20, + center: ['55%', '50%'], + radius: ['40%', '65%'], + clockwise: true, + avoidLabelOverlap: true, + hoverOffset: 15, + label: { + show: true, + position: 'outside', + formatter: '{a|{b}:{c}}{e|({d}%)}\n', + // color: '#FFFFFF', + textBorderWidth: 0, + rich: { + a: { + padding: [-15, 0, 0, 0], + fontSize: 15, + // color: '#FFFFFF', + textBorderWidth: 0, + textShadow: 'none', + }, + e: { + fontSize: 14, + // color: '#FFFFFF', + padding: [-15, 0, 0, 5], + textBorderWidth: 0, + textShadow: 'none', + }, + }, + }, + labelLine: { + normal: { + length: 5, + length2: 3, + smooth: true, + }, + }, + data: this.state.linkSum.map((item) => ({ + name: item.name, + value: item.qty, + })), + }, + ], + }; + + this.echartsInstances.dangerOperation.setOption(option); + + // 监听窗口大小变化 + const resizeHandler = () => { + if (this.echartsInstances.dangerOperation) { + this.echartsInstances.dangerOperation.resize(); + } + }; + + // 移除旧的监听器 + if (this.dangerOperationResizeHandler) { + window.removeEventListener('resize', this.dangerOperationResizeHandler); + } + + this.dangerOperationResizeHandler = resizeHandler; + window.addEventListener('resize', resizeHandler); + }; + backLog = () => { + if (this.echartsInstances.backLogChart) { + this.echartsInstances.backLogChart.dispose(); + this.echartsInstances.backLogChart = null; + } + + let backLogCharts = document.getElementById('backLogChart'); + if (!backLogCharts) { + requestAnimationFrame(() => { + this.backLogChart(); + }); + return; + } + const barTopColor = [ + ['#75baf3', '#2177d5'], + ['#ffa94d', '#f76707'], + ['#99ca6e', '#48a447'], + ]; + + this.echartsInstances.backLogChart = echarts.init(backLogCharts); + let xdata = []; + xdata = this.transformDat(this.state.taskTop3, barTopColor, 2); + // 创建图例的渐变色块 + const legendColors = barTopColor.map((gradient) => gradient[0]); + this.echartsInstances.backLogChart.setOption({ + title: { + text: '各事项排名前三名统计', + textStyle: { + fontSize: 16, + color: '#fff', + }, + }, + tooltip: { + trigger: 'axis', + axisPointer: { + // 坐标轴指示器,坐标轴触发有效 + type: 'shadow', // 默认为直线,可选为:'line' | 'shadow' + }, + }, + legend: { + data: xdata.legendData.map((name, index) => ({ + name: name, + // 使用渐变的起始颜色作为图例颜色 + // icon: 'rect', + itemStyle: { + color: legendColors[index], + borderWidth: 0, + }, + textStyle: { + color: '#fff', + fontSize: 14, + }, + })), + align: 'right', + right: 10, + itemGap: 16, + itemWidth: 18, + itemHeight: 12, + textStyle: { + color: '#fff', + fontStyle: 'normal', + fontFamily: '微软雅黑', + fontSize: 14, + }, + }, + color: legendColors, // 设置全局颜色 + + grid: { + left: '3%', + right: '4%', + bottom: '3%', + containLabel: true, + }, + xAxis: [ + { + type: 'category', + data: xdata.companyNames, + textStyle: { + fontSize: 18, + color: '#ffffff', + }, + //坐标轴 + axisLine: { + lineStyle: { + color: '#3eb2e8', + }, + }, + //坐标值标注 + axisLabel: { + show: true, + textStyle: { + color: '#fff', + }, + }, + }, + ], + yAxis: [ + { + type: 'value', + textStyle: { + fontSize: 14, + color: '#ffffff', + }, + //坐标轴 + axisLine: { + show: false, + }, + //坐标值标注 + axisLabel: { + show: true, + textStyle: { + color: '#fff', + }, + }, + //分格线 + splitLine: { + lineStyle: { + color: '#4784e8', + }, + }, + }, + ], + series: xdata.series, + }); + + // 监听resize + const resizeHandler = () => { + if (this.echartsInstances.backLogChart) { + this.echartsInstances.backLogChart.resize(); + } + }; + + if (this.backLogResizeHandler) { + window.removeEventListener('resize', this.backLogResizeHandler); + } + + this.backLogResizeHandler = resizeHandler; + window.addEventListener('resize', resizeHandler); + }; + completeChart = () => { + if (this.echartsInstances.completeone) { + this.echartsInstances.completeone.dispose(); + this.echartsInstances.completeone = null; + } + + let completeCharts = document.getElementById('completeone'); + if (!completeCharts) { + requestAnimationFrame(() => { + this.completeChart(); + }); + return; + } + + this.echartsInstances.completeone = echarts.init(completeCharts); + let seriesArr = []; + let centerArr = [ + ['20%', '50%'], + ['50%', '50%'], + ['80%', '50%'], + ]; + const completeData = this.state.jobFinishRate + .filter((item) => item.name === '班前会议' || item.name === '岗位当班' || item.name === '岗位交接班') + .map((item) => { + return { + name: item.name, + value: item.rate, + }; + }); + const colorArr = [ + [ + [0.2, '#2ec7c9'], + [0.8, '#b6a2de'], + [1, '#5ab1ef'], + ], + [ + [0.2, '#5470c6'], + [0.8, '#91cc75'], + [1, '#fac858'], + ], + [ + [0.2, '#4ea397'], + [0.8, '#22c3aa'], + [1, '#7bd9a5'], + ], + ]; + completeData.forEach((item, index) => { + seriesArr.push({ + center: centerArr[index], + axisLine: { + show: true, + lineStyle: { + color: colorArr[index], + width: 8, + }, + radius: '90%', // 控制轴线本身的半径 + }, + axisTick: { + show: false, + }, + splitLine: { + length: 8, // 刻度线长度 + distance: 25, // 向内移动距离,负值越大越向内 + lineStyle: { + color: '#fff', // 刻度线颜色 + width: 1, // 刻度线宽度 + }, + }, + axisLabel: { + distance: 15, // 标签与刻度线的距离 + textStyle: { + color: '#fff', + fontSize: 10, + }, + // 调整标签偏移 + offset: [0, 0], // [水平偏移, 垂直偏移] + }, + itemStyle: { + normal: { + color: 'auto', + }, + }, + radius: '80%', + pointer: { + show: true, + width: '8%', + length: '30%', + }, + title: { + textStyle: { + // fontWeight: 'bolder', + fontSize: 14, + color: '#fff', + }, + offsetCenter: [0, '100%'], + }, + detail: { + textStyle: { + fontWeight: 'bolder', + fontSize: 16, + color: '#fff', + }, + offsetCenter: [0, '68%'], + formatter: '{value}%', + // formatter: '{value}万\n(5048人)', + }, + min: 0, + max: 100, + // name: '米类仪表盘', + type: 'gauge', + show: false, + splitNumber: 10, + data: [ + { + name: item.name, + value: item.value, + }, + ], + }); + }); + this.echartsInstances.completeone.setOption({ + series: seriesArr, + }); + + // 监听resize + const resizeHandler = () => { + if (this.echartsInstances.completeone) { + this.echartsInstances.completeone.resize(); + } + }; + + if (this.completeResizeHandler) { + window.removeEventListener('resize', this.completeResizeHandler); + } + + this.completeResizeHandler = resizeHandler; + window.addEventListener('resize', resizeHandler); + }; + safedanger = () => { + if (this.echartsInstances.opretionTrend) { + this.echartsInstances.opretionTrend.dispose(); + this.echartsInstances.opretionTrend = null; + } + + const opretionTrends = document.getElementById('opretionTrend'); + if (!opretionTrends) { + requestAnimationFrame(() => { + this.safedanger(); + }); + return; + } + + this.echartsInstances.opretionTrend = echarts.init(opretionTrends); + + // ... 原有配置代码 + let bgColor = '#000'; + let color = [ + '#0090FF', + '#36CE9E', + '#e690d1', + '#FF515A', + '#8B5CFF', + '#00CA69', + '#FFC107', + '#E91E63', + '#9C27B0', + '#3F51B5', + '#2196F3', + '#4CAF50', + '#FF9800', + '#795548', + '#607D8B', + ]; + const seriesNames = []; + this.state.listSETrainSum.map((item) => { + seriesNames.push(item.CN); + }); + + // 生成x轴数据(12个月) + let xAxisData = []; + xAxisData = Object.keys( + this.state.listSETrainSum[0] === undefined || this.state.listSETrainSum[0] === null + ? {} + : this.state.listSETrainSum[0] + ) + .filter((key) => key.startsWith('dtNowYM')) + .map((key) => this.state.listSETrainSum[0][key].substring(0, 7)) + .sort((a, b) => new Date(a) - new Date(b)); // 按日期升序 + + let yAxisData = []; + yAxisData = this.state.listSETrainSum.map((item) => { + const values = []; + for (let i = 0; i <= 5; i++) { + const key = i === 0 ? 'SUM_TRAIN_HOUR' : `SUM_TRAIN_HOUR_${i}`; + values.push(item[key]); + } + return values; + }); + + // 生成15个系列的数据 + let seriesArr = []; + for (let i = 0; i < this.state.listSETrainSum.length; i++) { + seriesArr.push({ + name: seriesNames[i], + type: 'line', + smooth: true, + symbolSize: 6, + data: yAxisData[i], + }); + } + + const hexToRgba = (hex, opacity) => { + let rgbaColor = ''; + let reg = /^#[\da-f]{6}$/i; + if (reg.test(hex)) { + rgbaColor = `rgba(${parseInt('0x' + hex.slice(1, 3))},${parseInt('0x' + hex.slice(3, 5))},${parseInt( + '0x' + hex.slice(5, 7) + )},${opacity})`; + } + return rgbaColor; + }; + const option = { + title: [ + { + text: '各家公司的安全教育培训学时统计', + x: 'center', + y: '5%', + textStyle: { + fontSize: 16, + color: '#fff', + }, + }, + ], + backgroundColor: '', + color: color, + legend: { + type: 'scroll', // 如果项目多可以使用滚动 + orient: 'vertical', // 设置为垂直排列 + right: 10, // 距离右侧的距离 + top: 'center', // 垂直居中 + align: 'left', // 文本左对齐 + textStyle: { + color: '#fff', // 文字颜色 + fontSize: 12, + }, + itemStyle: { + color: 'inherit', + borderWidth: 0, + opacity: 1, + }, + symbol: 'rect', // 实心矩形 + symbolSize: [12, 8], // 大小 + itemWidth: 10, // 图例标记的宽度 + itemHeight: 10, // 图例标记的高度 + itemGap: 15, // 图例每项之间的间隔 + pageButtonItemGap: 3, + pageButtonGap: 5, + pageButtonPosition: 'end', + pageIconColor: '#00caf7', + width: 100, // 限制宽度 + height: 250, // 限制高度,超出就会显示滚动 + }, + tooltip: { + trigger: 'axis', + formatter: function (params) { + let html = ''; + params.forEach((v) => { + html += `
+ + ${v.seriesName} + ${v.value} + `; + }); + + return html; + }, + extraCssText: 'background: #fff; border-radius: 0;box-shadow: 0 0 3px rgba(0, 0, 0, 0.2);color: #333;', + axisPointer: { + type: 'shadow', + shadowStyle: { + // color: "#ffffff", + shadowColor: 'rgba(225,225,225,1)', + shadowBlur: 5, + }, + }, + }, + grid: { + top: '15%', + left: '5%', + right: '15%', // 为图例留出空间 + bottom: '15%', + containLabel: true, + }, + xAxis: [ + { + type: 'category', + boundaryGap: false, + axisLabel: { + textStyle: { + color: '#fff', + }, + }, + axisTick: { + show: false, + }, + axisLine: { + lineStyle: { + color: '#fff', + }, + }, + data: xAxisData, + }, + ], + yAxis: [ + { + type: 'value', + axisLabel: { + textStyle: { + color: '#fff', + }, + }, + nameTextStyle: { + color: '#fff', + fontSize: 12, + lineHeight: 40, + }, + splitLine: { + show: false, + lineStyle: { + type: 'dashed', + color: '#fff', + }, + }, + axisLine: { + show: false, + lineStyle: { + color: '#00c7ff', + width: 1, + type: 'solid', + }, + }, + axisTick: { + show: false, + }, + }, + ], + series: seriesArr, + }; + + this.echartsInstances.opretionTrend.setOption(option); + // 监听resize + const resizeHandler = () => { + if (this.echartsInstances.opretionTrend) { + this.echartsInstances.opretionTrend.resize(); + } + }; + + if (this.trendResizeHandler) { + window.removeEventListener('resize', this.trendResizeHandler); + } + + this.trendResizeHandler = resizeHandler; + window.addEventListener('resize', resizeHandler); + }; render() { const width = 1920, @@ -974,6 +1153,31 @@ class FullScreen extends React.Component { // 固定好16:9的宽高比,计算出最合适的缩放比,宽高比可根据需要自行更改 const { scale, safetySloganOne, animationDuration, sliderColor, sliderSize, activeTab } = this.state; const renderContent = () => { + const riskChangeData = [ + { + name: '隐患数', + value: this.state.hiddenRectify.qty, + }, + { + name: '按期整改数', + value: this.state.hiddenRectify.ontimeQty, + }, + { + name: '延期整改数', + value: this.state.hiddenRectify.delayQty, + }, + ]; + const chartConfig = { + data: this.state.safeCheckSum.map((item) => ({ + name: item.company, + value: item.qty, + })), + showValue: true, + }; + const meetingData = this.state.jobFinishRate.map((item) => ({ + name: item.name, + value: item.qty, + })); if (activeTab === '首页') { return ( <> @@ -1018,10 +1222,10 @@ class FullScreen extends React.Component { item.riskType === '重大风险' ? '#c92a2a' : item.riskType === '较大风险' - ? '#FF6710' - : item.riskType === '一般风险' - ? '#FFDD1E' - : '#0091FF', + ? '#FF6710' + : item.riskType === '一般风险' + ? '#FFDD1E' + : '#0091FF', margin: '10px 20px', padding: '5px 10px', fontSize: '16px', @@ -1069,6 +1273,7 @@ class FullScreen extends React.Component { justifyContent: 'center', width: '100%', height: '100%', + padding: '10px', }} >
-
+
+
+
@@ -1194,11 +1412,21 @@ class FullScreen extends React.Component { justifyContent: 'center', width: '100%', height: '100%', + padding: '10px', }} > -
- -
+
@@ -1246,30 +1474,31 @@ class FullScreen extends React.Component { }} > - {this.state.meetingData.map((item, index) => ( - -
-
-
-
{item.name}
-
- {item.value} - - 次 - + {meetingData && + meetingData.map((item, index) => ( + +
+
+
+
{item.name}
+
+ {item.value} + + 次 + +
-
- - ))} + + ))}
@@ -1303,23 +1532,24 @@ class FullScreen extends React.Component { }} >
- {this.state.riskChangeData.map((item, index) => ( -
-
-
-
{item.name}
-
{item.value}
+ {riskChangeData && + riskChangeData.map((item, index) => ( +
+
+
+
{item.name}
+
{item.value}
+
-
- ))} + ))}
整改率
-
83.98%
+
{this.state.hiddenRectify.rate}%
@@ -1369,7 +1599,7 @@ class FullScreen extends React.Component { 各家公司安全检查统计 - +
@@ -1453,22 +1683,23 @@ class FullScreen extends React.Component { marginLeft: 'auto', }} > - {this.state.configBanner.slice(0, 3).map((item, index) => ( -
this.handleTabClick(item.name)} - onKeyPress={(e) => e.key === 'Enter' && this.handleTabClick(item.name)} - tabIndex={0} - title={`点击进入${item.name}`} - role="button" - style={{ cursor: 'pointer' }} - > - {item.name} -
- ))} + {this.state.configBanner && + this.state.configBanner.slice(0, 3).map((item, index) => ( +
this.handleTabClick(item)} + onKeyPress={(e) => e.key === 'Enter' && this.handleTabClick(item)} + tabIndex={0} + title={`点击进入${item}`} + role="button" + style={{ cursor: 'pointer' }} + > + {item} +
+ ))}
@@ -1493,22 +1724,21 @@ class FullScreen extends React.Component { style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', height: '100%' }} >
- {this.state.configBanner.slice(3, 6).map((item, index) => ( -
this.handleTabClick(item.name)} - onKeyPress={(e) => e.key === 'Enter' && this.handleTabClick(item.name)} - tabIndex={0} - title={`点击进入${item.name}`} - role="button" - style={{ cursor: 'pointer' }} - > - {item.name} -
- ))} + {this.state.configBanner && + this.state.configBanner.slice(3, 6).map((item, index) => ( +
this.handleTabClick(item)} + onKeyPress={(e) => e.key === 'Enter' && this.handleTabClick(item)} + tabIndex={0} + title={`点击进入${item}`} + role="button" + style={{ cursor: 'pointer' }} + > + {item} +
+ ))}
{/* {this.state.nowWeek} */} diff --git a/src/layout/fullinter.less b/src/layout/fullinter.less index 409a83a..78156c9 100644 --- a/src/layout/fullinter.less +++ b/src/layout/fullinter.less @@ -137,14 +137,14 @@ } .otherTabContent { flex: 1; // 占据剩余空间 - width: 100%; + // width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; background: rgba(2, 20, 40, 0.7); border-radius: 10px; - margin: 10px; + margin: 0px 10px 10px 10px; border: 1px solid rgba(0, 202, 247, 0.3); } .row {