Compare commits
19 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e909784dee | |||
| cacfdf53c2 | |||
| b5602d4981 | |||
| 3d42b358d0 | |||
| 612deda821 | |||
| 448082e74f | |||
| b9f191459f | |||
| 39a75ef213 | |||
| 6133117039 | |||
| aba16e68c2 | |||
| f13e543c0a | |||
| ab954d3695 | |||
| 7029191579 | |||
| 3e7205e5b4 | |||
| e9153c3b41 | |||
| e83594bbbc | |||
| d56573acbb | |||
| b619c8b90b | |||
| 6c1435c7ff |
13
package.json
@@ -1,6 +1,7 @@
|
||||
{
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"server": "nodemon --watch websocket/**/*.ts --exec ts-node websocket/server.ts",
|
||||
"start": "umi dev",
|
||||
"build": "umi build",
|
||||
"postinstall": "umi generate tmp",
|
||||
@@ -25,9 +26,10 @@
|
||||
"antd": "^4.20.6",
|
||||
"echarts": "^5.3.2",
|
||||
"echarts-for-react": "^3.0.2",
|
||||
"framer-motion": "^6.5.1",
|
||||
"framer-motion": "^6.3.3",
|
||||
"less": "^4.1.3",
|
||||
"less-loader": "^11.0.0",
|
||||
"moment": "^2.29.4",
|
||||
"react": "^16.8.6",
|
||||
"react-dom": "^16.8.6",
|
||||
"react-router-dom": "^6.3.0",
|
||||
@@ -36,16 +38,19 @@
|
||||
"umi": "^3.5.23"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^20.6.0",
|
||||
"@types/ws": "^8.5.5",
|
||||
"nodemon": "^3.0.1",
|
||||
"ws": "^8.14.1",
|
||||
"ts-node": "^10.9.1",
|
||||
"@babel/runtime": "^7.18.0",
|
||||
"@types/node": "^20.8.10",
|
||||
"@types/react": "^17.0.0",
|
||||
"@types/react-dom": "^17.0.0",
|
||||
"@types/ws": "^8.5.8",
|
||||
"@umijs/preset-react": "1.x",
|
||||
"@umijs/test": "^3.5.23",
|
||||
"lint-staged": "^10.0.7",
|
||||
"prettier": "^2.2.0",
|
||||
"typescript": "^4.9.5",
|
||||
"typescript": "^5.2.2",
|
||||
"yorkie": "^2.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
|
Before Width: | Height: | Size: 32 MiB After Width: | Height: | Size: 6.3 MiB |
BIN
src/assets/Icon/icon-signal.png
Normal file
|
After Width: | Height: | Size: 777 B |
|
Before Width: | Height: | Size: 2.2 MiB |
|
Before Width: | Height: | Size: 2.3 MiB |
|
Before Width: | Height: | Size: 2.7 MiB |
BIN
src/assets/energy-bg.png
Normal file
|
After Width: | Height: | Size: 464 KiB |
|
Before Width: | Height: | Size: 426 KiB |
BIN
src/assets/good-bg.png
Normal file
|
After Width: | Height: | Size: 641 KiB |
BIN
src/assets/kiln-bg.png
Normal file
|
After Width: | Height: | Size: 359 KiB |
|
Before Width: | Height: | Size: 2.9 KiB |
|
Before Width: | Height: | Size: 63 KiB |
|
Before Width: | Height: | Size: 44 KiB |
|
Before Width: | Height: | Size: 117 KiB |
|
Before Width: | Height: | Size: 57 KiB |
|
Before Width: | Height: | Size: 68 KiB |
|
Before Width: | Height: | Size: 44 KiB |
|
Before Width: | Height: | Size: 1.7 MiB |
BIN
src/assets/smoke-bg.png
Normal file
|
After Width: | Height: | Size: 561 KiB |
|
Before Width: | Height: | Size: 394 KiB |
|
Before Width: | Height: | Size: 714 KiB |
@@ -6,8 +6,7 @@ function BottomBarItem(props) {
|
||||
<Container
|
||||
icon={props.icon}
|
||||
title={props.title}
|
||||
className={`${cls.bottomBarItem} ${props.className}`}
|
||||
style={props.style}
|
||||
className={`${props.className}`}
|
||||
>
|
||||
{props.children}
|
||||
</Container>
|
||||
1
src/components/BottomBar/BottomBarItem/index.module.css
Normal file
@@ -0,0 +1 @@
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
import cls from './index.module.css';
|
||||
import GraphBase from '../GraphBase';
|
||||
import BottomBarItem from '../BottomBarItem';
|
||||
import { Switch, Radio } from 'antd';
|
||||
import ReactECharts from 'echarts-for-react';
|
||||
import * as echarts from 'echarts';
|
||||
import { randomInt } from '../../../utils';
|
||||
|
||||
function FaultTotal(props) {
|
||||
const options = {
|
||||
@@ -136,27 +139,33 @@ function FaultTotal(props) {
|
||||
},
|
||||
};
|
||||
|
||||
function handleDateChange(v) {
|
||||
console.log('date ', v);
|
||||
}
|
||||
|
||||
// 根据使用的页面决定背景的大小
|
||||
const bgSize =
|
||||
props.page == 'home' ? ['middle', 'short'] : ['middle', 'long'];
|
||||
|
||||
return (
|
||||
<GraphBase
|
||||
icon="battery"
|
||||
title="产线当日缺陷分类"
|
||||
dateOptions={['日', '周', '月', '年']}
|
||||
onDateChange={handleDateChange}
|
||||
size={bgSize}
|
||||
style={{ width: '600px' }}
|
||||
>
|
||||
<BottomBarItem icon="chart" title="产线缺陷统计" className={cls.faultTotal}>
|
||||
<div className={cls.headWidget}>
|
||||
{/* 日周月年 */}
|
||||
<Radio.Group
|
||||
defaultValue="week"
|
||||
buttonStyle="solid"
|
||||
className={cls.radioGroup}
|
||||
>
|
||||
<Radio.Button value="day" className="radio-group__item">
|
||||
日
|
||||
</Radio.Button>
|
||||
<Radio.Button value="week" className="radio-group__item">
|
||||
周
|
||||
</Radio.Button>
|
||||
<Radio.Button value="month" className="radio-group__item">
|
||||
月
|
||||
</Radio.Button>
|
||||
<Radio.Button value="year" className="radio-group__item">
|
||||
年
|
||||
</Radio.Button>
|
||||
</Radio.Group>
|
||||
</div>
|
||||
<div className={cls.chart}>
|
||||
<ReactECharts option={options} style={{ height: '100%' }} />
|
||||
</div>
|
||||
</GraphBase>
|
||||
</BottomBarItem>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -4,13 +4,14 @@
|
||||
}
|
||||
|
||||
.faultTotal {
|
||||
height: 100%;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.headWidget {
|
||||
position: absolute;
|
||||
/* background: #00ee33; */
|
||||
top: 20px;
|
||||
top: 28px;
|
||||
right: 24px;
|
||||
height: 32px;
|
||||
width: 190px;
|
||||
@@ -1,6 +1,9 @@
|
||||
import cls from './index.module.css';
|
||||
import GraphBase from '../GraphBase';
|
||||
import BottomBarItem from '../BottomBarItem';
|
||||
import { Switch, Radio } from 'antd';
|
||||
import ReactECharts from 'echarts-for-react';
|
||||
import * as echarts from 'echarts';
|
||||
import { randomInt } from '../../../utils';
|
||||
import { useState } from 'react';
|
||||
|
||||
function FaultType(props) {
|
||||
@@ -15,10 +18,10 @@ function FaultType(props) {
|
||||
'#12FFF5',
|
||||
],
|
||||
grid: {
|
||||
left: 24,
|
||||
top: 10,
|
||||
bottom: 10,
|
||||
right: 24,
|
||||
left: 0,
|
||||
top: 0,
|
||||
bottom: 0,
|
||||
right: 0,
|
||||
},
|
||||
legend: {
|
||||
icon: 'circle',
|
||||
@@ -35,11 +38,11 @@ function FaultType(props) {
|
||||
},
|
||||
textStyle: {
|
||||
color: '#DFF1FE',
|
||||
fontSize: 18,
|
||||
fontSize: 16,
|
||||
rich: {
|
||||
sub: {
|
||||
color: '#fff9',
|
||||
fontSize: 18,
|
||||
fontSize: 16,
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -59,6 +62,16 @@ function FaultType(props) {
|
||||
labelLine: {
|
||||
length: 0,
|
||||
},
|
||||
// emphasis: {
|
||||
// label: {
|
||||
// show: true,
|
||||
// fontSize: 40,
|
||||
// fontWeight: 'bold',
|
||||
// },
|
||||
// },
|
||||
// labelLine: {
|
||||
// show: false,
|
||||
// },
|
||||
data: [
|
||||
{ value: 1048, name: '缺陷1' },
|
||||
{ value: 735, name: '缺陷2' },
|
||||
@@ -79,28 +92,34 @@ function FaultType(props) {
|
||||
{ id: 4, label: '产线4', value: 'l4' },
|
||||
{ id: 5, label: '产线5', value: 'l5' },
|
||||
]);
|
||||
|
||||
function handleDateChange(v) {
|
||||
console.log('date ', v);
|
||||
}
|
||||
|
||||
// 根据使用的页面决定背景的大小
|
||||
const bgSize =
|
||||
props.page == 'home' ? ['middle', 'short'] : ['middle', 'short'];
|
||||
|
||||
return (
|
||||
<GraphBase
|
||||
icon="battery"
|
||||
<BottomBarItem
|
||||
icon="puzzle"
|
||||
title="产线当日缺陷分类"
|
||||
dateOptions={lines.map((item) => item.label)}
|
||||
onDateChange={handleDateChange}
|
||||
size={bgSize}
|
||||
style={{ width: '600px' }}
|
||||
className={cls.faultType}
|
||||
>
|
||||
<div className={cls.headWidget}>
|
||||
{/* 日周月年 */}
|
||||
<Radio.Group
|
||||
defaultValue="l1"
|
||||
buttonStyle="solid"
|
||||
className={cls.radioGroup}
|
||||
>
|
||||
{lines.map((l, index) => (
|
||||
<Radio.Button
|
||||
key={l.label}
|
||||
value={l.value}
|
||||
className={`radio-group__item ${cls['radio-group__item']}`}
|
||||
>
|
||||
{l.label}
|
||||
</Radio.Button>
|
||||
))}
|
||||
</Radio.Group>
|
||||
</div>
|
||||
<div className={cls.chart}>
|
||||
<ReactECharts option={options} style={{ height: '100%' }} />
|
||||
</div>
|
||||
</GraphBase>
|
||||
</BottomBarItem>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -4,11 +4,12 @@
|
||||
|
||||
.faultType {
|
||||
position: relative;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.headWidget {
|
||||
position: absolute;
|
||||
top: 20px;
|
||||
top: 28px;
|
||||
right: 24px;
|
||||
height: 32px;
|
||||
width: 340px;
|
||||
@@ -32,3 +33,7 @@
|
||||
color: #fff !important;
|
||||
background: #03233c !important;
|
||||
}
|
||||
|
||||
.radio-group__item {
|
||||
padding: 0 8px;
|
||||
}
|
||||
45
src/components/BottomBar/SpecPL/index.jsx
Normal file
@@ -0,0 +1,45 @@
|
||||
import { useState } from 'react';
|
||||
import cls from './index.module.less';
|
||||
import { ScrollBoard } from '@jiaminghi/data-view-react';
|
||||
import BottomBarItem from '../BottomBarItem';
|
||||
|
||||
const TodayTableData = (props) => {
|
||||
const [config, setConfig] = useState({
|
||||
// headerBGC: 'rgba(4, 44, 76, 0.3)',
|
||||
// headerBGC: 'rgba(4, 44, 76, .8)',
|
||||
headerBGC: '#044A8425',
|
||||
header: [
|
||||
'<span style="color:#fff">产线名<span/>',
|
||||
'<span style="color:#fff">原板宽度<span/>',
|
||||
'<span style="color:#fff">净板宽度<span/>',
|
||||
'<span style="color:#fff">玻璃厚度<span/>',
|
||||
],
|
||||
// oddRowBGC: '#042444',
|
||||
oddRowBGC: '#044A8425',
|
||||
// evenRowBGC: '#042c4c',
|
||||
evenRowBGC: '#0B549945',
|
||||
columnWidth: [90],
|
||||
headerHeight: 40,
|
||||
hoverPause: false,
|
||||
data: [
|
||||
['产线1', '1000mm', '1000mm', '3.2mm'],
|
||||
['产线2', '100mm', '100mm', '2.2mm'],
|
||||
['产线3', '100mm', '100mm', '2.0mm'],
|
||||
['产线4', '100mm', '100mm', '2.1mm'],
|
||||
['产线5', '100mm', '100mm', '2.2mm'],
|
||||
],
|
||||
});
|
||||
return (
|
||||
<BottomBarItem icon="signal" title="当前产线生产规格" className={cls.spec}>
|
||||
<div className={cls.todayTableData}>
|
||||
<ScrollBoard
|
||||
config={config}
|
||||
className={cls.tableClass}
|
||||
style={{ height: '100%' }}
|
||||
/>
|
||||
</div>
|
||||
</BottomBarItem>
|
||||
);
|
||||
};
|
||||
|
||||
export default TodayTableData;
|
||||
7
src/components/BottomBar/SpecPL/index.module.less
Normal file
@@ -0,0 +1,7 @@
|
||||
.spec {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.todayTableData {
|
||||
height: 100%;
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
// 助燃风流量
|
||||
import cls from './index.module.css';
|
||||
import BottomBarItem from '../BottomItemBackground';
|
||||
import BottomBarItem from '../BottomBarItem';
|
||||
import ReactECharts from 'echarts-for-react';
|
||||
import * as echarts from 'echarts';
|
||||
import { randomInt } from '../../../utils';
|
||||
@@ -10,7 +10,7 @@ import SocketContext from '../../../store/socket-data-provider';
|
||||
|
||||
function GasI(props) {
|
||||
const [showChart, setShowChart] = useState(true);
|
||||
const { runState, hisState } = useContext(SocketContext);
|
||||
const { realtimeState, hisState } = useContext(SocketContext);
|
||||
|
||||
let dataList = [];
|
||||
let seriesData = [];
|
||||
@@ -27,23 +27,36 @@ function GasI(props) {
|
||||
let options = null;
|
||||
if (showChart) {
|
||||
// keys() 结果不是按照顺序,需要 sort()
|
||||
seriesData = hisState?.combustionAir
|
||||
? Object.keys(hisState.combustionAir)
|
||||
seriesData = hisState?.wind
|
||||
? Object.keys(hisState.wind)
|
||||
.sort()
|
||||
.map((key) => hisState.combustionAir[key])
|
||||
.map((key) => hisState.wind[key])
|
||||
: Array(8)
|
||||
.fill(1)
|
||||
.map((_) => Array(7).fill(0));
|
||||
seriesData.unshift(hisState?.wind['FE_totalair'] || 1);
|
||||
seriesData.splice(8, 1);
|
||||
|
||||
// debug
|
||||
console.log(
|
||||
'助燃风 chart series data',
|
||||
hisState?.combustionAir,
|
||||
seriesData,
|
||||
);
|
||||
// console.log('助燃风 chart series data', hisState?.wind, seriesData);
|
||||
options = {
|
||||
color: colors,
|
||||
grid: { top: 32, right: 12, bottom: 20, left: 48 },
|
||||
legend: {
|
||||
show: true,
|
||||
icon: 'roundRect',
|
||||
top: 10,
|
||||
right: 10,
|
||||
padding: 0,
|
||||
itemWidth: 8,
|
||||
itemHeight: 8,
|
||||
itemGap: 3,
|
||||
height: 8,
|
||||
textStyle: {
|
||||
color: '#DFF1FE',
|
||||
fontSize: 10,
|
||||
},
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
data: Array(7)
|
||||
@@ -64,12 +77,13 @@ function GasI(props) {
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
width: 1,
|
||||
color: '#213259',
|
||||
color: '#4561AE',
|
||||
// color: '#213259',
|
||||
},
|
||||
},
|
||||
},
|
||||
yAxis: {
|
||||
name: '单位/m³',
|
||||
name: '单位m³/h',
|
||||
nameTextStyle: {
|
||||
color: '#fff',
|
||||
fontSize: 10,
|
||||
@@ -83,12 +97,14 @@ function GasI(props) {
|
||||
axisLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
color: '#213259',
|
||||
color: '#4561AE',
|
||||
// color: '#213259',
|
||||
},
|
||||
},
|
||||
splitLine: {
|
||||
lineStyle: {
|
||||
color: '#213259a0',
|
||||
color: '#4561AEa0',
|
||||
// color: '#213259a0',
|
||||
},
|
||||
},
|
||||
// interval: 10,
|
||||
@@ -96,7 +112,7 @@ function GasI(props) {
|
||||
// max: 100,
|
||||
},
|
||||
series: seriesData.map((v, i) => ({
|
||||
name: i + 1 + '#助燃风',
|
||||
name: i ? i + '#助燃风' : '助燃风总流量',
|
||||
data: v,
|
||||
type: 'line',
|
||||
symbol: 'circle',
|
||||
@@ -113,8 +129,9 @@ function GasI(props) {
|
||||
},
|
||||
};
|
||||
} else {
|
||||
dataList = runState?.combustionAirPressureArr
|
||||
dataList = realtimeState?.wind
|
||||
? [
|
||||
{ id: 0, name: '助燃风总流量', value: '0m³/h' },
|
||||
{ id: 1, name: '1#助燃风', value: '0m³/h' },
|
||||
{ id: 2, name: '2#助燃风', value: '0m³/h' },
|
||||
{ id: 3, name: '3#助燃风', value: '0m³/h' },
|
||||
@@ -122,12 +139,12 @@ function GasI(props) {
|
||||
{ id: 5, name: '5#助燃风', value: '0m³/h' },
|
||||
{ id: 6, name: '6#助燃风', value: '0m³/h' },
|
||||
{ id: 7, name: '7#助燃风', value: '0m³/h' },
|
||||
{ id: 8, name: '8#助燃风', value: '0m³/h' },
|
||||
].map((item, index) => ({
|
||||
...item,
|
||||
value: runState.combustionAirPressureArr[index] ?? '/',
|
||||
value: realtimeState.wind[index] ?? '/',
|
||||
}))
|
||||
: [
|
||||
{ id: 0, name: '助燃风总流量', value: '0m³/h' },
|
||||
{ id: 1, name: '1#助燃风', value: '0m³/h' },
|
||||
{ id: 2, name: '2#助燃风', value: '0m³/h' },
|
||||
{ id: 3, name: '3#助燃风', value: '0m³/h' },
|
||||
@@ -135,10 +152,7 @@ function GasI(props) {
|
||||
{ id: 5, name: '5#助燃风', value: '0m³/h' },
|
||||
{ id: 6, name: '6#助燃风', value: '0m³/h' },
|
||||
{ id: 7, name: '7#助燃风', value: '0m³/h' },
|
||||
{ id: 8, name: '8#助燃风', value: '0m³/h' },
|
||||
];
|
||||
// debug
|
||||
console.log('助燃风 实时 data', runState?.combustionAirPressureArr);
|
||||
}
|
||||
|
||||
function handleSwitchChange(val) {
|
||||
@@ -149,12 +163,7 @@ function GasI(props) {
|
||||
}
|
||||
}
|
||||
return (
|
||||
<BottomBarItem
|
||||
icon="pause"
|
||||
title="助燃风流量"
|
||||
className={cls.gas}
|
||||
style={props.style}
|
||||
>
|
||||
<BottomBarItem icon="pause" title="助燃风流量" className={cls.gas}>
|
||||
<div className={cls.headWidget}>
|
||||
<div className="flex items-center">
|
||||
<Switch size="small" defaultChecked onChange={handleSwitchChange} />
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
.gas {
|
||||
position: relative;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.currentFlow {
|
||||
@@ -25,7 +26,7 @@
|
||||
.headWidget {
|
||||
position: absolute;
|
||||
/* background: #00ee33; */
|
||||
top: 20px;
|
||||
top: 28px;
|
||||
right: 24px;
|
||||
height: 32px;
|
||||
width: 190px;
|
||||
@@ -68,7 +69,7 @@
|
||||
.headWidget {
|
||||
position: absolute;
|
||||
/* background: #00ee33; */
|
||||
top: 22px;
|
||||
top: 28px;
|
||||
right: 24px;
|
||||
height: 32px;
|
||||
width: 410px;
|
||||
@@ -50,12 +50,13 @@ export default function getOptions(seriesData, name) {
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
width: 1,
|
||||
color: '#213259',
|
||||
// color: '#213259',
|
||||
color: '#4561AE',
|
||||
},
|
||||
},
|
||||
},
|
||||
yAxis: {
|
||||
name: '单位m³/h',
|
||||
name: '单位Nm³/h',
|
||||
nameTextStyle: {
|
||||
color: '#fff',
|
||||
fontSize: 10,
|
||||
@@ -69,18 +70,22 @@ export default function getOptions(seriesData, name) {
|
||||
},
|
||||
axisLine: {
|
||||
show: true,
|
||||
// lineStyle: {
|
||||
// color: '#213259',
|
||||
// },
|
||||
lineStyle: {
|
||||
color: '#213259',
|
||||
color: '#4561AE',
|
||||
},
|
||||
},
|
||||
splitLine: {
|
||||
lineStyle: {
|
||||
color: '#213259a0',
|
||||
// color: '#213259a0',
|
||||
color: '#4561AEa0',
|
||||
},
|
||||
},
|
||||
},
|
||||
series: seriesData.map((arr, index) => ({
|
||||
name: index + 1 + '#' + name,
|
||||
name: index !== 0 ? index + '#' + name : '天然气总流量',
|
||||
data: arr,
|
||||
type: 'line',
|
||||
areaStyle: {
|
||||
@@ -8,8 +8,8 @@ function GasChart(props) {
|
||||
const { dataSource } = props;
|
||||
const { hisState } = useContext(SocketContext);
|
||||
|
||||
const dataName = dataSource == 'gas-i' ? 'kilnGasT1' : 'kilnGasT2';
|
||||
|
||||
// const dataName = dataSource == 'gas-i' ? 'kilnGasT1' : 'kilnGasT2';
|
||||
const dataName = 'gas';
|
||||
// keys() 的结果不是按照顺序的,需要 sort()
|
||||
const seriesData = hisState?.[dataName]
|
||||
? Object.keys(hisState?.[dataName])
|
||||
@@ -18,7 +18,7 @@ function GasChart(props) {
|
||||
: Array(dataSource == 'gas-i' ? 8 : 4).fill(Array(7).fill(0));
|
||||
|
||||
// debug
|
||||
console.log('天然气 series data', dataName, hisState?.[dataName], seriesData);
|
||||
// console.log('天然气 series data', dataName, hisState?.[dataName], seriesData);
|
||||
|
||||
return (
|
||||
<div className={cls.gasChart}>
|
||||
@@ -26,7 +26,7 @@ function GasChart(props) {
|
||||
key={Math.random()}
|
||||
option={getOptions(
|
||||
seriesData,
|
||||
dataSource == 'gas-i' ? '天然气I' : '天然气II',
|
||||
dataSource == 'gas-i' ? '天然气' : '天然气II',
|
||||
)}
|
||||
style={{ height: '100%' }}
|
||||
/>
|
||||
@@ -7,14 +7,14 @@ function getData(type) {
|
||||
switch (type) {
|
||||
case 'gas-i':
|
||||
data = [
|
||||
{ id: 1, name: '1#天然气I', value: '0m³/h' },
|
||||
{ id: 2, name: '2#天然气I', value: '0m³/h' },
|
||||
{ id: 3, name: '3#天然气I', value: '0m³/h' },
|
||||
{ id: 4, name: '4#天然气I', value: '0m³/h' },
|
||||
{ id: 5, name: '5#天然气I', value: '0m³/h' },
|
||||
{ id: 6, name: '6#天然气I', value: '0m³/h' },
|
||||
{ id: 7, name: '7#天然气I', value: '0m³/h' },
|
||||
{ id: 8, name: '8#天然气I', value: '0m³/h' },
|
||||
{ id: 0, name: '天然气总流量', value: '0Nm³/h' },
|
||||
{ id: 1, name: '1#天然气', value: '0Nm³/h' },
|
||||
{ id: 2, name: '2#天然气', value: '0Nm³/h' },
|
||||
{ id: 3, name: '3#天然气', value: '0Nm³/h' },
|
||||
{ id: 4, name: '4#天然气', value: '0Nm³/h' },
|
||||
{ id: 5, name: '5#天然气', value: '0Nm³/h' },
|
||||
{ id: 6, name: '6#天然气', value: '0Nm³/h' },
|
||||
{ id: 7, name: '7#天然气', value: '0Nm³/h' },
|
||||
];
|
||||
break;
|
||||
case 'gas-ii':
|
||||
@@ -31,12 +31,16 @@ function getData(type) {
|
||||
}
|
||||
|
||||
function GridList(props) {
|
||||
const { runState } = useContext(SocketContext);
|
||||
const key = props.dataSource == 'gas-i' ? 'gasFlowArr' : 'furnaceGasFlowArr';
|
||||
const { realtimeState } = useContext(SocketContext);
|
||||
// const key = props.dataSource == 'gas-i' ? 'gasFlowArr' : 'furnaceGasFlowArr';
|
||||
|
||||
let dataList = getData(props.dataSource);
|
||||
dataList = runState?.[key]
|
||||
? dataList.map((v, i) => ({ ...v, value: runState[key][i] ?? '/' }))
|
||||
// dataList = realtimeState?.[key]
|
||||
dataList = realtimeState?.['gasii']
|
||||
? dataList.map((v, i) => ({
|
||||
...v,
|
||||
value: realtimeState['gasii'][i] ?? '/',
|
||||
}))
|
||||
: dataList;
|
||||
|
||||
return (
|
||||
@@ -1,6 +1,6 @@
|
||||
// 天然气流量
|
||||
import cls from './index.module.css';
|
||||
import BottomBarItem from '../BottomItemBackground';
|
||||
import BottomBarItem from '../BottomBarItem';
|
||||
|
||||
import { Switch, Radio } from 'antd';
|
||||
import { useState } from 'react';
|
||||
@@ -19,24 +19,19 @@ function GasII(props) {
|
||||
}
|
||||
}
|
||||
|
||||
function handleSourceChange(e) {
|
||||
console.log('val', e.target.value);
|
||||
if (e.target.value == 'ii') {
|
||||
// 天然气II
|
||||
setDataSource('gas-ii');
|
||||
} else if (e.target.value == 'i') {
|
||||
// 天然气 I
|
||||
setDataSource('gas-i');
|
||||
}
|
||||
}
|
||||
// function handleSourceChange(e) {
|
||||
// console.log('val', e.target.value);
|
||||
// if (e.target.value == 'ii') {
|
||||
// // 天然气II
|
||||
// setDataSource('gas-ii');
|
||||
// } else if (e.target.value == 'i') {
|
||||
// // 天然气 I
|
||||
// setDataSource('gas-i');
|
||||
// }
|
||||
// }
|
||||
|
||||
return (
|
||||
<BottomBarItem
|
||||
icon="pause"
|
||||
title="天然气流量"
|
||||
className={`${cls.gas} ${props.className}`}
|
||||
style={props.style}
|
||||
>
|
||||
<BottomBarItem icon="pause" title="天然气流量" className={cls.gas}>
|
||||
{/* legend */}
|
||||
<div className={cls.headWidget}>
|
||||
<div className="flex items-center">
|
||||
@@ -45,7 +40,7 @@ function GasII(props) {
|
||||
{!showChart && <span className={cls.switchLabel}>实时流量</span>}
|
||||
</div>
|
||||
|
||||
<Radio.Group
|
||||
{/* <Radio.Group
|
||||
defaultValue="i"
|
||||
buttonStyle="solid"
|
||||
className={cls.radioGroup}
|
||||
@@ -57,7 +52,7 @@ function GasII(props) {
|
||||
<Radio.Button value="ii" className="radio-group__item">
|
||||
天然气 II
|
||||
</Radio.Button>
|
||||
</Radio.Group>
|
||||
</Radio.Group> */}
|
||||
</div>
|
||||
|
||||
<div className={cls.chart}>
|
||||
@@ -4,11 +4,12 @@
|
||||
|
||||
.gas {
|
||||
position: relative;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.currentFlow {
|
||||
position: absolute;
|
||||
top: 20px;
|
||||
top: 28px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
padding: 8px 22px;
|
||||
@@ -23,7 +24,7 @@
|
||||
|
||||
.headWidget {
|
||||
position: absolute;
|
||||
top: 22px;
|
||||
top: 28px;
|
||||
right: 24px;
|
||||
height: 32px;
|
||||
width: 410px;
|
||||
21
src/components/BottomBar/index.jsx
Normal file
@@ -0,0 +1,21 @@
|
||||
import React from 'react';
|
||||
import { useEffect, useState } from 'react';
|
||||
|
||||
import GasI from './gasi';
|
||||
import GasII from './gasii';
|
||||
import FaultTotal from './FaultTotal';
|
||||
import FaultType from './FaultType';
|
||||
|
||||
import './index.less';
|
||||
import cls from './index.module.css';
|
||||
|
||||
export default function index() {
|
||||
return (
|
||||
<div className={`${cls.bottomBar} flex justify-between`}>
|
||||
<FaultTotal />
|
||||
<FaultType />
|
||||
<GasII />
|
||||
<GasI />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,9 +1,8 @@
|
||||
.centerMenu {
|
||||
position: fixed;
|
||||
top: 120px;
|
||||
left: 1340px;
|
||||
position: absolute;
|
||||
top: 20px;
|
||||
left: 680px;
|
||||
color: white;
|
||||
z-index: 10000;
|
||||
}
|
||||
|
||||
.menuItem {
|
||||
@@ -1,18 +1,21 @@
|
||||
import React, { useState, useContext, useEffect } from 'react';
|
||||
import React, { useState, useContext, useEffect, useMemo } from 'react';
|
||||
import SocketContext from '../../../store/socket-data-provider';
|
||||
import icon1 from '@/assets/CenterChart2icon1.svg';
|
||||
import icon2 from '@/assets/CenterChart2icon2.svg';
|
||||
import icon3 from '@/assets/CenterChart2icon3.svg';
|
||||
import icon4 from '@/assets/CenterChart2icon4.svg';
|
||||
// import icon4 from '@/assets/CenterChart2icon4.svg';
|
||||
|
||||
import cls from './leftbox.module.less';
|
||||
|
||||
const Chart2 = () => {
|
||||
const ctx = useContext(SocketContext);
|
||||
let [time, setTime] = useState([0, 0]);
|
||||
const { runState } = useContext(SocketContext);
|
||||
const [time, setTime] = useState([0, 0]);
|
||||
|
||||
// console.clear();
|
||||
// console.log('>>>>>>>> runstate 更新 (', runState, ')');
|
||||
|
||||
useEffect(() => {
|
||||
const restTime = ctx.runState?.lastFireChangeTime;
|
||||
const restTime = runState?.lastFireChangeTime;
|
||||
if (restTime == null) return;
|
||||
console.log('restTime is:', restTime);
|
||||
let timer = null;
|
||||
@@ -71,23 +74,38 @@ const Chart2 = () => {
|
||||
return () => {
|
||||
clearInterval(timer);
|
||||
};
|
||||
}, [ctx.runState?.lastFireChangeTime]);
|
||||
}, [runState?.lastFireChangeTime, runState?.updateKey]);
|
||||
|
||||
const lastFireChangeTime = {
|
||||
icon: icon3,
|
||||
label: '剩余时间',
|
||||
value: `${time[0]}分${time[1]}秒`,
|
||||
};
|
||||
|
||||
const fireChangeTime = useMemo(() => {
|
||||
return runState?.fireChangeTime || '00:00';
|
||||
}, [runState?.fireChangeTime]);
|
||||
|
||||
const fireDirection = useMemo(() => {
|
||||
// let lastValue = null;
|
||||
// if (runState?.fireDirection) {
|
||||
// lastValue = runState?.fireDirection;
|
||||
// }
|
||||
// console.log('换火方向: <', runState?.fireDirection, '>')
|
||||
return runState?.fireDirection || '南火';
|
||||
}, [runState?.fireDirection]);
|
||||
|
||||
const data = [
|
||||
{
|
||||
icon: icon1,
|
||||
label: '换火时间',
|
||||
value: ctx.runState?.fireChangeTime || '00:00',
|
||||
},
|
||||
{
|
||||
icon: icon3,
|
||||
label: '剩余时间',
|
||||
value: `${time[0]}分${time[1]}秒`,
|
||||
value: fireChangeTime,
|
||||
},
|
||||
lastFireChangeTime,
|
||||
{
|
||||
icon: icon2,
|
||||
label: '当前火向',
|
||||
value: ctx.runState?.fireDirection || '东火',
|
||||
value: fireDirection,
|
||||
},
|
||||
];
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
.leftbox {
|
||||
// width: 440px;
|
||||
// background: rgb(127, 202, 42);
|
||||
height: 98px;
|
||||
|
||||
.box {
|
||||
margin-right: 16px;
|
||||
@@ -46,7 +46,7 @@ function replaceStyle(Arr, opencity) {
|
||||
class Chart1 extends Component {
|
||||
render() {
|
||||
return (
|
||||
<div className="CenterChart1itemDetailBorder" style={{ opacity: 0.75 }}>
|
||||
<div className="CenterChart1itemDetailBorder">
|
||||
<h2 className="CenterChart1itemTXT"> 当前产线生产规格</h2>
|
||||
<div className="CenterChart1itemContainer">
|
||||
<span className="CenterFormitemDetailBorderLine1"></span>
|
||||
@@ -0,0 +1,52 @@
|
||||
.CenterChart1itemDetailBorder {
|
||||
width: 100%;
|
||||
height: 240px;
|
||||
display: flex;
|
||||
flex-direction:column;
|
||||
justify-content: flex-start;
|
||||
|
||||
background-color: rgba(4, 44, 76, 0.2);
|
||||
.CenterChart1itemTXT {
|
||||
width: 100%;
|
||||
height: 10%;
|
||||
font-size: 20px;
|
||||
color:rgba(255,255,255,0.8);
|
||||
text-align: center;
|
||||
margin-top: 2%;
|
||||
|
||||
}
|
||||
.CenterChart1itemContainer {
|
||||
|
||||
width: 95%;
|
||||
height:100px;
|
||||
position:relative;
|
||||
|
||||
.CenterFormitemDetailBorderLine1 {
|
||||
width: 1px;
|
||||
height: 200px;
|
||||
background-color:#041c2c;
|
||||
float: left;
|
||||
margin-left: 18%;
|
||||
z-index: 10;
|
||||
position: absolute;
|
||||
}
|
||||
.CenterFormitemDetailBorderLine2 {
|
||||
width: 1px;
|
||||
height: 200px;
|
||||
background-color:#041c2c;
|
||||
float: left;
|
||||
margin-left: 46%;
|
||||
z-index: 10;
|
||||
position: absolute;
|
||||
}
|
||||
.CenterFormitemDetailBorderLine3 {
|
||||
width: 1px;
|
||||
height: 200px;
|
||||
background-color:#041c2c;
|
||||
float: left;
|
||||
margin-left: 72%;
|
||||
z-index: 10;
|
||||
position: absolute;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,14 @@
|
||||
import React from 'react';
|
||||
import CenterMenu from './CenterMenu';
|
||||
import Item2 from './RightTable';
|
||||
import Item1 from '../../../公共组件/时间火向数据';
|
||||
import Item1 from './LeftBoxes';
|
||||
|
||||
import cls from './index.module.less';
|
||||
|
||||
export default function index() {
|
||||
return (
|
||||
<>
|
||||
<CenterMenu />
|
||||
<div className="flex justify-between w-full h-full">
|
||||
<div className={cls.leftGrid}>
|
||||
<Item1 />
|
||||
8
src/components/CenterTopData/index.module.less
Normal file
@@ -0,0 +1,8 @@
|
||||
.leftGrid {
|
||||
// width: 416px;
|
||||
height: 212px;
|
||||
}
|
||||
.rightTable {
|
||||
width: 410px;
|
||||
height: 240px;
|
||||
}
|
||||
@@ -1,15 +1,51 @@
|
||||
import { useEffect, useRef } from 'react';
|
||||
import useIcon from '../hooks/useIcon';
|
||||
|
||||
import cls from './container.module.less';
|
||||
|
||||
import IconStack from '../assets/Icon/icon-stack.png';
|
||||
import IconGood from '../assets/Icon/icon-good.png';
|
||||
import IconCharger from '../assets/Icon/icon-charge.png';
|
||||
import IconSmoke from '../assets/Icon/icon-taiji.png';
|
||||
import IconChart from '../assets/Icon/icon-chart.png';
|
||||
import IconPuzzle from '../assets/Icon/icon-puzzle.png';
|
||||
import IconPause from '../assets/Icon/icon-pause.png';
|
||||
import IconSignal from '../assets/Icon/icon-signal.png';
|
||||
|
||||
const Container = (props) => {
|
||||
let icon = useIcon(props.icon);
|
||||
let icon = useRef(null);
|
||||
|
||||
switch (props.icon) {
|
||||
case 'kiln':
|
||||
icon.current = IconStack;
|
||||
break;
|
||||
case 'good': // 良品率
|
||||
icon.current = IconGood;
|
||||
break;
|
||||
case 'charger':
|
||||
icon.current = IconCharger;
|
||||
break;
|
||||
case 'smoke':
|
||||
icon.current = IconSmoke;
|
||||
break;
|
||||
case 'chart':
|
||||
icon.current = IconChart;
|
||||
break;
|
||||
case 'puzzle':
|
||||
icon.current = IconPuzzle;
|
||||
break;
|
||||
case 'pause':
|
||||
icon.current = IconPause;
|
||||
break;
|
||||
case 'signal':
|
||||
icon.current = IconSignal;
|
||||
break;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={`${cls.container} ${props.className}`} style={props.style}>
|
||||
<div className={`${cls.container} ${props.className}`}>
|
||||
<div className={cls.container__head}>
|
||||
<img
|
||||
src={icon}
|
||||
src={icon.current}
|
||||
alt="#"
|
||||
className={props.icon == 'kiln' ? cls.bigger : ''}
|
||||
/>
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import React, { useEffect, useState, useRef } from 'react';
|
||||
|
||||
import TopSide from '../../../assets/TopSide.png';
|
||||
import LeftLine from '../../../assets/TopTitleLeftIcon.png';
|
||||
import RightLine from '../../../assets/TopTitleRightIcon.png';
|
||||
import ButtonLine from '../../../assets/TopButtonLine.png';
|
||||
import TopSide from '../../assets/TopSide.png';
|
||||
import LeftLine from '../../assets/TopTitleLeftIcon.png';
|
||||
import RightLine from '../../assets/TopTitleRightIcon.png';
|
||||
import ButtonLine from '../../assets/TopButtonLine.png';
|
||||
import './index.less';
|
||||
|
||||
export default function index() {
|
||||
88
src/components/Head/index.less
Normal file
@@ -0,0 +1,88 @@
|
||||
.TopTitleBoder {
|
||||
width: 3840px;
|
||||
height: 84px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
|
||||
.TopSideRight {
|
||||
margin-top: 40px;
|
||||
margin-right: 40px;
|
||||
width: 493px;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
.TopSideLeft {
|
||||
margin-left: 40px;
|
||||
margin-top: 40px;
|
||||
width: 493px;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
.TopSideLeftLine {
|
||||
background: url('../../assets/TopTitleLeft.png');
|
||||
width: 899px;
|
||||
height: 40px;
|
||||
margin-top: 42px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: right;
|
||||
|
||||
.TopSideLeftLineicon {
|
||||
margin-right: 40px;
|
||||
margin-top: 25px;
|
||||
width: 204.32px;
|
||||
height: 2.79px;
|
||||
}
|
||||
|
||||
.TopSideLeftTxt {
|
||||
margin-right: 120px;
|
||||
margin-top: 15px;
|
||||
color: rgb(255, 255, 255, 0.8);
|
||||
font-size: 20px;
|
||||
font-weight: 300px;
|
||||
line-height: 22.174976px;
|
||||
}
|
||||
}
|
||||
|
||||
.TopSiderightLine {
|
||||
background: url('../../assets/TopTitleRight.png');
|
||||
width: 899px;
|
||||
height: 40px;
|
||||
margin-top: 42px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: left;
|
||||
|
||||
.TopSideRightLineicon {
|
||||
margin-left: 40px;
|
||||
margin-top: 25px;
|
||||
width: 204.32px;
|
||||
height: 2.79px;
|
||||
}
|
||||
|
||||
.TopSideRightTxt {
|
||||
margin-left: 120px;
|
||||
margin-top: 15px;
|
||||
color: rgb(255, 255, 255, 0.8);
|
||||
font-size: 20px;
|
||||
font-weight: 600px;
|
||||
line-height: 22.174976px;
|
||||
}
|
||||
}
|
||||
|
||||
.TopButtonLine {
|
||||
margin-top: -9px;
|
||||
width: 760px;
|
||||
height: 14px;
|
||||
}
|
||||
|
||||
.TopTitleText {
|
||||
margin-top: 16px;
|
||||
letter-spacing: 8px;
|
||||
font-size: 32px;
|
||||
color: #00fff7;
|
||||
text-align: center;
|
||||
letter-spacing: 2px;
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
import cls from './good.module.less';
|
||||
import Container from '../../Container';
|
||||
import TodayTableData from './components/TodayTableData';
|
||||
import GoodRateChart from './components/GoodRateChart';
|
||||
import TechSplitline from '../TechSplitline';
|
||||
import Container from '../Container';
|
||||
import TodayTableData from './substitutionCharts/TodayTableData';
|
||||
import GoodRateChart from './substitutionCharts/GoodRateChart';
|
||||
import TechSplitline from './substitutionCharts/TechSplitline';
|
||||
|
||||
const GoodProduction = () => {
|
||||
return (
|
||||
35
src/components/LeftBar/Kiln.jsx
Normal file
@@ -0,0 +1,35 @@
|
||||
import React from 'react';
|
||||
import { useState, useEffect, useContext } from 'react';
|
||||
import Container from '../Container';
|
||||
import SocketContext from '../../store/socket-data-provider';
|
||||
import cls from './kiln.module.less';
|
||||
|
||||
export default function Kiln() {
|
||||
const ctx = useContext(SocketContext);
|
||||
|
||||
const infos = [
|
||||
{ label: '窑炉压力', value: ctx.kilnInfo?.kilnPressure || '0Pa' },
|
||||
{ label: '循环水温度', value: ctx.kilnInfo?.waterLoopTemperature || '0℃' },
|
||||
{ label: '循环水流量', value: ctx.kilnInfo?.waterLoopFlow || '0㎡/h' },
|
||||
{ label: '循环水压力', value: ctx.kilnInfo?.waterLoopPressure || '0Pa' },
|
||||
{ label: '助燃风压力', value: ctx.kilnInfo?.windPressure || '0℃' },
|
||||
{ label: '碹顶加权温度', value: ctx.kilnInfo?.topTemperature || '0℃' },
|
||||
{
|
||||
label: '压缩气压力',
|
||||
value: ctx.kilnInfo?.gasPressure || '0Pa',
|
||||
},
|
||||
{ label: '熔化加权温度', value: ctx.kilnInfo?.meltTemperature || '0℃' },
|
||||
];
|
||||
|
||||
return (
|
||||
<Container title="窑炉信息" icon="kiln" className={cls.leftBar__top}>
|
||||
<div className={cls.leftBar__top__content}>
|
||||
{infos.map((item) => (
|
||||
<div key={item.label} className={cls.info__item}>
|
||||
{item.label}: {item.value}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
10
src/components/LeftBar/good.module.less
Normal file
@@ -0,0 +1,10 @@
|
||||
.goodProd {
|
||||
background: url(../../assets/good-bg.png) no-repeat;
|
||||
background-size: 100% 100%;
|
||||
height: 610px;
|
||||
|
||||
.goodProd__content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
}
|
||||
14
src/components/LeftBar/index.jsx
Normal file
@@ -0,0 +1,14 @@
|
||||
import React from 'react';
|
||||
import Kiln from './Kiln';
|
||||
import GoodProduction from './GoodProduction';
|
||||
|
||||
import cls from './index.module.less';
|
||||
|
||||
export default function index() {
|
||||
return (
|
||||
<div className={cls.leftBar}>
|
||||
<Kiln />
|
||||
<GoodProduction />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
8
src/components/LeftBar/index.module.less
Normal file
@@ -0,0 +1,8 @@
|
||||
.leftBar {
|
||||
width: 625px;
|
||||
height: 100%;
|
||||
margin-left: 40px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 22px;
|
||||
}
|
||||
@@ -1,9 +1,7 @@
|
||||
.leftBar__top {
|
||||
width: 625px;
|
||||
// height: 305px;
|
||||
height: 300px;
|
||||
background: url('../../../assets/ItemBg.png') no-repeat;
|
||||
background: url('../../assets/kiln-bg.png') no-repeat;
|
||||
background-size: 100% 100%;
|
||||
height: 306px;
|
||||
|
||||
.leftBar__top__content {
|
||||
flex: 1;
|
||||
@@ -11,7 +9,7 @@
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 10px;
|
||||
padding-top: 18px;
|
||||
padding-top: 8px;
|
||||
|
||||
.info__item {
|
||||
border-radius: 2px;
|
||||
@@ -3,12 +3,12 @@ import './overwrite.css'; // 覆写 antd 默认样式,全局
|
||||
import ReactECharts from 'echarts-for-react';
|
||||
import * as echarts from 'echarts';
|
||||
import { Switch, Radio } from 'antd';
|
||||
import { randomInt } from '../../../../../utils';
|
||||
import { randomInt } from '../../../../utils';
|
||||
|
||||
const GoodRateChart = (props) => {
|
||||
const options = {
|
||||
color: ['#FFD160', '#12FFF5', '#2760FF'],
|
||||
grid: { top: 28, right: 12, bottom: 32, left: 48 },
|
||||
grid: { top: 28, right: 12, bottom: 48, left: 48 },
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
data: Array(7)
|
||||
@@ -29,7 +29,7 @@ const GoodRateChart = (props) => {
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
width: 1,
|
||||
color: '#213259',
|
||||
color: '#4561AE',
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -43,12 +43,12 @@ const GoodRateChart = (props) => {
|
||||
axisLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
color: '#213259',
|
||||
color: '#4561AE',
|
||||
},
|
||||
},
|
||||
splitLine: {
|
||||
lineStyle: {
|
||||
color: '#213259a0',
|
||||
color: '#4561AEa0',
|
||||
},
|
||||
},
|
||||
interval: 10,
|
||||
@@ -112,16 +112,16 @@ const GoodRateChart = (props) => {
|
||||
|
||||
function handleSwitchChange(val) {
|
||||
// val: boolean
|
||||
console.log('switch change', val);
|
||||
// console.log('switch change', val);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={cls.GoodRateChart}>
|
||||
<div className={cls.titleBar}>
|
||||
<h2>生产良品率</h2>
|
||||
<Switch defaultChecked onChange={handleSwitchChange} />
|
||||
{/* <Switch defaultChecked onChange={handleSwitchChange} /> */}
|
||||
<div className={cls.legend}>
|
||||
<span className="legend__title">班次详情</span>
|
||||
{/* <span className="legend__title">班次详情</span> */}
|
||||
<ul className="legend__list">
|
||||
<li>总量</li>
|
||||
<li>白班</li>
|
||||
@@ -147,7 +147,7 @@ const GoodRateChart = (props) => {
|
||||
</Radio.Button>
|
||||
</Radio.Group>
|
||||
</div>
|
||||
<ReactECharts option={options} />
|
||||
<ReactECharts option={options} style={{ height: '100%' }} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -5,7 +5,8 @@ import { ScrollBoard } from '@jiaminghi/data-view-react';
|
||||
const TodayTableData = (props) => {
|
||||
const [config, setConfig] = useState({
|
||||
// headerBGC: 'rgba(4, 44, 76, 0.3)',
|
||||
headerBGC: 'rgba(4, 44, 76, .8)',
|
||||
// headerBGC: 'rgba(4, 44, 76, .8)',
|
||||
headerBGC: '#044A8425',
|
||||
header: [
|
||||
'<span style="color:#fff">产线<span/>',
|
||||
'<span style="color:#fff">一等率<span/>',
|
||||
@@ -13,8 +14,10 @@ const TodayTableData = (props) => {
|
||||
'<span style="color:#fff">成品率<span/>',
|
||||
'<span style="color:#fff">废品率<span/>',
|
||||
],
|
||||
oddRowBGC: '#042444',
|
||||
evenRowBGC: '#042c4c',
|
||||
// oddRowBGC: '#042444',
|
||||
oddRowBGC: '#044A8425',
|
||||
// evenRowBGC: '#042c4c',
|
||||
evenRowBGC: '#0B549945',
|
||||
columnWidth: [90],
|
||||
headerHeight: 40,
|
||||
hoverPause: false,
|
||||
@@ -28,7 +31,11 @@ const TodayTableData = (props) => {
|
||||
});
|
||||
return (
|
||||
<div className={cls.todayTableData}>
|
||||
<ScrollBoard config={config} style={{ width: '100%' }} />
|
||||
<ScrollBoard
|
||||
config={config}
|
||||
className={cls.tableClass}
|
||||
style={{ width: '100%' }}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -7,7 +7,7 @@ import ReactECharts from 'echarts-for-react';
|
||||
const EnergyCostChart = (props) => {
|
||||
const options = {
|
||||
color: ['#FFD160', '#12FFF5', '#2760FF'],
|
||||
grid: { top: 32, right: 12, bottom: 20, left: 48 },
|
||||
grid: { top: 26, right: 12, bottom: 18, left: 48 },
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
data: Array(7)
|
||||
@@ -33,7 +33,7 @@ const EnergyCostChart = (props) => {
|
||||
},
|
||||
},
|
||||
yAxis: {
|
||||
name: '单位/m³',
|
||||
name: '单位/kWh',
|
||||
nameTextStyle: {
|
||||
color: '#fff',
|
||||
fontSize: 10,
|
||||
@@ -43,7 +43,7 @@ const EnergyCostChart = (props) => {
|
||||
axisLabel: {
|
||||
color: '#fff',
|
||||
fontSize: 12,
|
||||
formatter: '{value} %',
|
||||
formatter: '{value}',
|
||||
},
|
||||
axisLine: {
|
||||
show: true,
|
||||
@@ -85,20 +85,43 @@ const EnergyCostChart = (props) => {
|
||||
|
||||
function handleSwitchChange(val) {
|
||||
// val: boolean
|
||||
console.log('switch change', val);
|
||||
// console.log('switch change', val);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={cls.energyCostChart}>
|
||||
<div className={cls.titleBar}>
|
||||
<h2>能耗趋势图</h2>
|
||||
<Switch defaultChecked onChange={handleSwitchChange} />
|
||||
{/* <Switch defaultChecked onChange={handleSwitchChange} /> */}
|
||||
<div className={cls.legend}>
|
||||
<span className="legend__title">班次详情</span>
|
||||
{/* <span className="legend__title">班次详情</span> */}
|
||||
<ul className="legend__list">
|
||||
<li>总量</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div className={cls.radioGroupWrapper}>
|
||||
<Radio.Group
|
||||
defaultValue="elecCost"
|
||||
buttonStyle="solid"
|
||||
className={cls.radioGroup}
|
||||
>
|
||||
<Radio.Button value="elecCost" className="radio-group__item">
|
||||
电耗能
|
||||
</Radio.Button>
|
||||
<Radio.Button value="restHeat" className="radio-group__item">
|
||||
余热发电
|
||||
</Radio.Button>
|
||||
<Radio.Button value="waterCost" className="radio-group__item">
|
||||
水耗能
|
||||
</Radio.Button>
|
||||
<Radio.Button value="gasCost" className="radio-group__item">
|
||||
天然气
|
||||
</Radio.Button>
|
||||
{/* <Radio.Button value="gasiiCost" className="radio-group__item">
|
||||
焦炉煤气
|
||||
</Radio.Button> */}
|
||||
</Radio.Group>
|
||||
<Radio.Group
|
||||
defaultValue="week"
|
||||
buttonStyle="solid"
|
||||
@@ -119,7 +142,7 @@ const EnergyCostChart = (props) => {
|
||||
</Radio.Group>
|
||||
</div>
|
||||
<div className="flex-1">
|
||||
<ReactECharts option={options} style={{ height: '180px' }} />
|
||||
<ReactECharts option={options} style={{ height: '145px' }} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
@@ -5,7 +5,7 @@
|
||||
}
|
||||
.energyCostChart .titleBar {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
align-items: center;
|
||||
color: white;
|
||||
}
|
||||
@@ -63,6 +63,13 @@
|
||||
background-color: #2760ff;
|
||||
}
|
||||
|
||||
.radioGroupWrapper {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin: 4px 0;
|
||||
}
|
||||
|
||||
.radioGroup * {
|
||||
border: none !important;
|
||||
border-radius: 0 !important;
|
||||
50
src/components/RightBar/EnergyCost/index.jsx
Normal file
@@ -0,0 +1,50 @@
|
||||
import cls from './index.module.less';
|
||||
import Container from '../../Container';
|
||||
import TechSplitline from '../TechSplitline';
|
||||
import EnergyCostChart from './EnergyCostChart';
|
||||
import SocketContext from '../../../store/socket-data-provider';
|
||||
import { useContext } from 'react';
|
||||
|
||||
function EnergyCost(props) {
|
||||
const { energyState = {} } = useContext(SocketContext);
|
||||
// console.log('energyState', energyState);
|
||||
// let {
|
||||
// restHeat = '0kWh',
|
||||
// water = '0Km³',
|
||||
// gasi = '0m³',
|
||||
// gasii = '0m³',
|
||||
// electricity = '0kWh',
|
||||
// } = energyState;
|
||||
let restHeat = energyState?.restHeat || '0kWh';
|
||||
let water = energyState?.water || '0m³';
|
||||
let gasi = energyState?.gasi || '0m³';
|
||||
let gasii = energyState?.gasii || '0m³';
|
||||
let electricity = energyState?.electricity || '0kWh';
|
||||
|
||||
return (
|
||||
<Container title="能耗" icon="charger" className={cls.energyCost}>
|
||||
<div className={`flex flex-col`}>
|
||||
<div className={`${cls.cost__info} flex`}>
|
||||
<div
|
||||
className={`${cls.info__item} ${cls.hAuto} flex flex-col justify-center items-center self-stretch`}
|
||||
>
|
||||
<span>余 热 发 电</span>
|
||||
<span>{restHeat}</span>
|
||||
</div>
|
||||
<div className={cls.info__item_groups}>
|
||||
<div className={cls.info__item}>水 耗 量 : {water}</div>
|
||||
<div className={cls.info__item}>天 然 气 : {gasi}</div>
|
||||
<div className={cls.info__item}>电 耗 量 : {electricity}</div>
|
||||
{/* <div className={cls.info__item}>天 然 气 II: {gasii}</div> */}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<TechSplitline />
|
||||
|
||||
<EnergyCostChart />
|
||||
</div>
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
|
||||
export default EnergyCost;
|
||||
@@ -1,13 +1,13 @@
|
||||
.energyCost {
|
||||
background: url(../../../assets/energy.png) no-repeat;
|
||||
background: url(../../../assets/energy-bg.png) no-repeat;
|
||||
background-size: 100% 100%;
|
||||
width: 626px;
|
||||
height: 400px;
|
||||
height: 395px;
|
||||
}
|
||||
|
||||
.cost__info {
|
||||
margin-top: 4px;
|
||||
margin-bottom: 12px;
|
||||
// margin-bottom: 12px;
|
||||
|
||||
div {
|
||||
flex-grow: 1;
|
||||
@@ -19,7 +19,7 @@
|
||||
color: hsl(0, 0%, 100%, 0.9);
|
||||
box-shadow: inset 0 0 17px 0px hsla(0, 0%, 100%, 0.15);
|
||||
// width: 288px;
|
||||
height: 43px;
|
||||
height: 40px;
|
||||
font-size: 20px;
|
||||
letter-spacing: 1.43px;
|
||||
line-height: 40px;
|
||||
@@ -35,5 +35,5 @@
|
||||
margin-left: 8px;
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 8px;
|
||||
gap: 6px;
|
||||
}
|
||||
@@ -8,7 +8,7 @@ import ReactECharts from 'echarts-for-react';
|
||||
const SmokeTrendChart = (props) => {
|
||||
const options = {
|
||||
color: ['#FFD160', '#12FFF5', '#2760FF'],
|
||||
grid: { top: 38, right: 12, bottom: 20, left: 48 },
|
||||
grid: { top: 32, right: 12, bottom: 18, left: 48 },
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
data: Array(7)
|
||||
@@ -34,7 +34,7 @@ const SmokeTrendChart = (props) => {
|
||||
},
|
||||
},
|
||||
yAxis: {
|
||||
name: '单位m³/h',
|
||||
name: '单位mg/m³',
|
||||
nameTextStyle: {
|
||||
color: '#fff',
|
||||
fontSize: 10,
|
||||
@@ -44,7 +44,7 @@ const SmokeTrendChart = (props) => {
|
||||
axisLabel: {
|
||||
color: '#fff',
|
||||
fontSize: 12,
|
||||
formatter: '{value} %',
|
||||
formatter: '{value}',
|
||||
},
|
||||
axisLine: {
|
||||
show: true,
|
||||
@@ -125,9 +125,9 @@ const SmokeTrendChart = (props) => {
|
||||
<div className={cls.energyCostChart}>
|
||||
<div className={cls.titleBar}>
|
||||
<h2>烟气趋势图</h2>
|
||||
<Switch defaultChecked onChange={handleSwitchChange} />
|
||||
{/* <Switch defaultChecked onChange={handleSwitchChange} /> */}
|
||||
<div className={cls.legend}>
|
||||
<span className="legend__title">班次详情</span>
|
||||
{/* <span className="legend__title">班次详情</span> */}
|
||||
<ul className="legend__list">
|
||||
<li>总量</li>
|
||||
<li>白班</li>
|
||||
@@ -138,13 +138,10 @@ const SmokeTrendChart = (props) => {
|
||||
|
||||
<div className={`${cls.choiceBar} flex items-center justify-between`}>
|
||||
<Radio.Group
|
||||
defaultValue="oxygen"
|
||||
defaultValue="so2"
|
||||
buttonStyle="solid"
|
||||
className={`${cls.radioGroup} flex items-center justify-between`}
|
||||
>
|
||||
<Radio.Button value="oxygen" className="radio-group__item">
|
||||
氧气含量
|
||||
</Radio.Button>
|
||||
<Radio.Button value="so2" className="radio-group__item">
|
||||
二氧化硫
|
||||
</Radio.Button>
|
||||
@@ -154,6 +151,9 @@ const SmokeTrendChart = (props) => {
|
||||
<Radio.Button value="no2" className="radio-group__item">
|
||||
二氧化氮
|
||||
</Radio.Button>
|
||||
<Radio.Button value="oxygen" className="radio-group__item">
|
||||
氧气含量
|
||||
</Radio.Button>
|
||||
</Radio.Group>
|
||||
|
||||
<Radio.Group
|
||||
@@ -175,7 +175,7 @@ const SmokeTrendChart = (props) => {
|
||||
</Radio.Button>
|
||||
</Radio.Group>
|
||||
</div>
|
||||
<ReactECharts option={options} style={{ height: '240px' }} />
|
||||
<ReactECharts option={options} style={{ height: '220px' }} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -7,7 +7,7 @@
|
||||
width: 400px;
|
||||
margin-bottom: 4px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
/* justify-content: space-between; */
|
||||
align-items: center;
|
||||
color: white;
|
||||
}
|
||||
@@ -13,7 +13,9 @@ function SmokeHandle(props) {
|
||||
<div className={cls.info__item}>二氧化硫排放浓度:59mg/m³</div>
|
||||
<div className={cls.info__item}>二氧化氮排放浓度:59mg/m³</div>
|
||||
</div>
|
||||
|
||||
<TechSplitline />
|
||||
|
||||
<SmokeTrendChart />
|
||||
</div>
|
||||
</Container>
|
||||
@@ -1,9 +1,9 @@
|
||||
.smokeHandle {
|
||||
// background: #b730305c;
|
||||
background: url(../../../assets/smoke.png) no-repeat;
|
||||
background: url(../../../assets/smoke-bg.png) no-repeat;
|
||||
background-size: 100% 100%;
|
||||
width: 626px;
|
||||
height: 540px;
|
||||
height: 512px;
|
||||
.smokeHandle__content {
|
||||
margin-top: 8px;
|
||||
}
|
||||
@@ -14,7 +14,7 @@
|
||||
color: hsl(0, 0%, 100%, 0.9);
|
||||
box-shadow: inset 0 0 17px 0px hsla(0, 0%, 100%, 0.15);
|
||||
// width: 288px;
|
||||
height: 56px;
|
||||
height: 52px;
|
||||
font-size: 20px;
|
||||
letter-spacing: 1.43px;
|
||||
line-height: 56px;
|
||||
@@ -23,7 +23,7 @@
|
||||
}
|
||||
|
||||
.info__item_groups {
|
||||
margin-bottom: 12px;
|
||||
// margin-bottom: 12px;
|
||||
margin-left: 8px;
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
7
src/components/RightBar/TechSplitline/index.jsx
Normal file
@@ -0,0 +1,7 @@
|
||||
import cls from './index.module.less';
|
||||
|
||||
const TechSplitline = (props) => {
|
||||
return <div className={cls.techSplitline}></div>;
|
||||
};
|
||||
|
||||
export default TechSplitline;
|
||||
5
src/components/RightBar/TechSplitline/index.module.less
Normal file
@@ -0,0 +1,5 @@
|
||||
.techSplitline {
|
||||
height: 2px;
|
||||
width: 100%;
|
||||
background: radial-gradient(#3ce7ff, #3ce8ff92, #3ce8ff32, transparent);
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
import React from 'react';
|
||||
import SmokeHandle from '../../../公共组件/烟气处理';
|
||||
import EnergyCost from '../../../公共组件/能耗';
|
||||
import SmokeHandle from './SmokeHandle';
|
||||
import EnergyCost from './EnergyCost';
|
||||
|
||||
import cls from './index.module.less';
|
||||
|
||||
17
src/components/Slider/index.jsx
Normal file
@@ -0,0 +1,17 @@
|
||||
import './slider.css';
|
||||
import { useState } from 'react';
|
||||
|
||||
const Slider = (props) => {
|
||||
const [v, setV] = useState(100);
|
||||
const handleInput = (e) => {
|
||||
setV(e.target.value);
|
||||
props.handleSlide(e.target.value);
|
||||
};
|
||||
return (
|
||||
<div id="slider" className="slider">
|
||||
<input type="range" value={v} onInput={handleInput} onChange={() => {}} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Slider;
|
||||
@@ -10,7 +10,7 @@
|
||||
align-items: center;
|
||||
|
||||
img {
|
||||
width: 20px;
|
||||
width: 24px;
|
||||
|
||||
&.bigger {
|
||||
width: 24px;
|
||||
@@ -24,7 +24,7 @@
|
||||
sans-serif;
|
||||
margin: 0;
|
||||
margin-left: 6px;
|
||||
font-size: 18px;
|
||||
font-size: 24px;
|
||||
color: #fff;
|
||||
letter-spacing: 2px;
|
||||
font-weight: 500;
|
||||
|
||||
5
src/components/yx-dark/Bottom.jsx
Normal file
@@ -0,0 +1,5 @@
|
||||
import './styles/bottom.module.css';
|
||||
|
||||
export default (props) => {
|
||||
return <div className={`bottom ${props.className}`}>{props.children}</div>;
|
||||
};
|
||||
26
src/components/yx-dark/Header.jsx
Normal file
@@ -0,0 +1,26 @@
|
||||
import React, { useEffect, useState, useRef } from 'react';
|
||||
import './styles/header.module.css';
|
||||
import moment from 'moment';
|
||||
|
||||
export default (props) => {
|
||||
let [today, setToday] = useState(new Date());
|
||||
moment.locale('zh-cn');
|
||||
setTimeout(() => {
|
||||
setToday(new Date());
|
||||
}, 1000);
|
||||
|
||||
return (
|
||||
<header className="header">
|
||||
<div>
|
||||
<span className="header--logo"></span>
|
||||
<h1>宜兴新能源生产线大数据指挥中心</h1>
|
||||
</div>
|
||||
<span className="header--wing absolute company">
|
||||
设计单位:中建材智能自动化研究院
|
||||
</span>
|
||||
<span className="header--wing absolute datetime">
|
||||
{moment(today).format('YYYY.M.D dddd HH:mm:ss')}
|
||||
</span>
|
||||
</header>
|
||||
);
|
||||
};
|
||||
13
src/components/yx-dark/LeftContent.jsx
Normal file
@@ -0,0 +1,13 @@
|
||||
import './styles/left.module.css';
|
||||
|
||||
import Kiln from '../LeftBar/Kiln';
|
||||
import GoodProduction from '../LeftBar/GoodProduction';
|
||||
|
||||
export default (props) => {
|
||||
return (
|
||||
<div className={`left-content ${props.className}`}>
|
||||
<Kiln />
|
||||
<GoodProduction />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
38
src/components/yx-dark/MainContainer.jsx
Normal file
@@ -0,0 +1,38 @@
|
||||
import Bottom from './Bottom';
|
||||
import LeftContent from './LeftContent';
|
||||
import RightContent from './RightContent';
|
||||
import './styles/main.module.css';
|
||||
|
||||
import FaultTotal from '../BottomBar/FaultTotal';
|
||||
import FaultType from '../BottomBar/FaultType';
|
||||
import GasFlow from '../BottomBar/gasii';
|
||||
import WindFlow from '../BottomBar/gasi';
|
||||
import SpecPL from '../BottomBar/SpecPL';
|
||||
import CenterTopBox from '../CenterTopData/LeftBoxes';
|
||||
|
||||
export default (props) => {
|
||||
return (
|
||||
<div className="main-container">
|
||||
<LeftContent className="left"></LeftContent>
|
||||
<div className="main-center">
|
||||
<CenterTopBox />
|
||||
</div>
|
||||
<Bottom title="产线缺陷统计" className="bottom-1">
|
||||
<FaultTotal />
|
||||
</Bottom>
|
||||
<Bottom title="产线当日缺陷分类" className="bottom-2">
|
||||
<FaultType />
|
||||
</Bottom>
|
||||
<Bottom title="天然气流量" className="bottom-3">
|
||||
<GasFlow />
|
||||
</Bottom>
|
||||
<Bottom title="助燃风流量" className="bottom-4">
|
||||
<WindFlow />
|
||||
</Bottom>
|
||||
<Bottom title="当前产线生产风格" className="bottom-5">
|
||||
<SpecPL />
|
||||
</Bottom>
|
||||
<RightContent className="right"></RightContent>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
13
src/components/yx-dark/RightContent.jsx
Normal file
@@ -0,0 +1,13 @@
|
||||
import './styles/right.module.css';
|
||||
|
||||
import Energy from '../RightBar/EnergyCost';
|
||||
import Smoke from '../RightBar/SmokeHandle';
|
||||
|
||||
export default (props) => {
|
||||
return (
|
||||
<div className={`right-content ${props.className}`}>
|
||||
<Energy />
|
||||
<Smoke />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
BIN
src/components/yx-dark/images/3d.png
Normal file
|
After Width: | Height: | Size: 5.8 MiB |
BIN
src/components/yx-dark/images/bg.png
Normal file
|
After Width: | Height: | Size: 1.2 MiB |
BIN
src/components/yx-dark/images/company.png
Normal file
|
After Width: | Height: | Size: 32 KiB |
BIN
src/components/yx-dark/images/date.png
Normal file
|
After Width: | Height: | Size: 6.3 KiB |
BIN
src/components/yx-dark/images/fenlei-bg.png
Normal file
|
After Width: | Height: | Size: 252 KiB |