update烟气

This commit is contained in:
lb 2023-12-28 16:16:31 +08:00
parent 4e73410495
commit 049a0804ac
6 changed files with 340 additions and 192 deletions

View File

@ -1,182 +1,199 @@
import cls from './index.module.css';
import { randomInt } from '../../../../utils';
import * as echarts from 'echarts';
import { Switch, Radio } from 'antd';
import ReactECharts from 'echarts-for-react';
import cls from "./index.module.css";
import { randomInt } from "../../../../utils";
import * as echarts from "echarts";
import { Radio } from "antd";
import ReactECharts from "echarts-for-react";
import { useState } from "react";
import { useSelector } from "react-redux";
const SmokeTrendChart = (props) => {
const options = {
color: ['#FFD160', '#12FFF5', '#2760FF'],
grid: { top: 38, right: 12, bottom: 20, left: 48 },
xAxis: {
type: 'category',
data: Array(7)
.fill(1)
.map((_, index) => {
const today = new Date();
const dtimestamp = today - index * 24 * 60 * 60 * 1000;
return `${new Date(dtimestamp).getMonth() + 1}.${new Date(
dtimestamp,
).getDate()}`;
})
.reverse(),
axisLabel: {
color: '#fff',
fontSize: 12,
},
axisTick: { show: false },
axisLine: {
lineStyle: {
width: 1,
color: '#213259',
},
},
},
yAxis: {
name: '单位m³/h',
nameTextStyle: {
color: '#fff',
fontSize: 10,
align: 'right',
},
type: 'value',
axisLabel: {
color: '#fff',
fontSize: 12,
formatter: '{value} %',
},
axisLine: {
show: true,
lineStyle: {
color: '#213259',
},
},
splitLine: {
lineStyle: {
color: '#213259a0',
},
},
interval: 10,
min: 0,
max: 100,
},
series: [
{
data: Array(7)
.fill(1)
.map((_) => {
return randomInt(60, 100);
}),
type: 'line',
areaStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: '#FFD16040' },
{ offset: 0.5, color: '#FFD16020' },
{ offset: 1, color: '#FFD16010' },
]),
},
// smooth: true,
},
{
data: Array(7)
.fill(1)
.map((_) => {
return randomInt(60, 100);
}),
type: 'line',
areaStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: '#12FFF540' },
{ offset: 0.5, color: '#12FFF520' },
{ offset: 1, color: '#12FFF510' },
]),
},
// smooth: true,
},
{
data: Array(7)
.fill(1)
.map((_) => {
return randomInt(60, 100);
}),
type: 'line',
areaStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: '#2760FF40' },
{ offset: 0.5, color: '#2760FF20' },
{ offset: 1, color: '#2760FF10' },
]),
},
// smooth: true,
},
],
tooltip: {
trigger: 'axis',
},
};
const dayTrend = useSelector((state) => state.smoke?.dayTrend);
const weekTrend = useSelector((state) => state.smoke?.weekTrend);
const monthTrend = useSelector((state) => state.smoke?.monthTrend);
const yearTrend = useSelector((state) => state.smoke?.yearTrend);
function handleSwitchChange(val) {
// val: boolean
}
const [source, setSource] = useState("O2_float");
const [period, setPeriod] = useState("day");
return (
<div className={cls.energyCostChart}>
<div className={cls.titleBar}>
<h2>烟气趋势图</h2>
<Switch defaultChecked onChange={handleSwitchChange} />
<div className={cls.legend}>
<span className="legend__title">班次详情</span>
<ul className="legend__list">
<li>总量</li>
<li>白班</li>
<li>夜班</li>
</ul>
</div>
</div>
const currentTrend =
period === "day"
? dayTrend
: period === "week"
? weekTrend
: period === "month"
? monthTrend
: yearTrend;
<div className={`${cls.choiceBar} flex items-center justify-between`}>
<Radio.Group
defaultValue="oxygen"
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>
<Radio.Button value="no" className="radio-group__item">
一氧化氮
</Radio.Button>
<Radio.Button value="no2" className="radio-group__item">
二氧化氮
</Radio.Button>
</Radio.Group>
const options = getOptions(source, period, currentTrend);
<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>
<ReactECharts option={options} style={{ height: '240px' }} />
</div>
);
return (
<div className={cls.energyCostChart}>
<div className={cls.titleBar}>
<h2>烟气趋势图</h2>
{/* <Switch defaultChecked onChange={handleSwitchChange} /> */}
{/* <div className={cls.legend}>
<span className="legend__title">班次详情</span>
<ul className="legend__list">
<li>总量</li>
<li>白班</li>
<li>夜班</li>
</ul>
</div> */}
</div>
<div className={`${cls.choiceBar} flex items-center justify-between`}>
<Radio.Group
value={source}
onChange={(e) => setSource(e.target.value)}
buttonStyle="solid"
className={`${cls.radioGroup} flex items-center justify-between`}
>
<Radio.Button value="O2_float" className="radio-group__item">
氧气
</Radio.Button>
<Radio.Button value="NOX_float" className="radio-group__item">
氮氧化物
</Radio.Button>
<Radio.Button value="SO2_float" className="radio-group__item">
二氧化硫
</Radio.Button>
<Radio.Button value="dust_float" className="radio-group__item">
颗粒物
</Radio.Button>
</Radio.Group>
<Radio.Group
value={period}
onChange={(e) => setPeriod(e.target.value)}
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>
<ReactECharts option={options} style={{ height: "240px" }} />
</div>
);
};
export default SmokeTrendChart;
function getOptions(source, period, trend) {
return {
color: ["#FFD160", "#12FFF5", "#2760FF"],
grid: { top: 38, right: 12, bottom: 20, left: 48 },
xAxis: {
type: "category",
// data: Array(7)
// .fill(1)
// .map((_, index) => {
// const today = new Date();
// const dtimestamp = today - index * 24 * 60 * 60 * 1000;
// return `${new Date(dtimestamp).getMonth() + 1}.${new Date(
// dtimestamp
// ).getDate()}`;
// })
// .reverse(),
data: trend[source].map((item) => item.time),
axisLabel: {
color: "#fff",
fontSize: 12,
},
axisTick: { show: false },
axisLine: {
lineStyle: {
width: 1,
color: "#213259",
},
},
},
yAxis: {
name: "单位m³/h",
nameTextStyle: {
color: "#fff",
fontSize: 10,
align: "right",
},
type: "value",
axisLabel: {
color: "#fff",
fontSize: 12,
formatter: "{value} %",
},
axisLine: {
show: true,
lineStyle: {
color: "#213259",
},
},
splitLine: {
lineStyle: {
color: "#213259a0",
},
},
// interval: 10,
// min: 0,
// max: 100,
},
series: [
{
data: trend[source].map((item) => item.value),
type: "line",
areaStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: "#FFD16040" },
{ offset: 0.5, color: "#FFD16020" },
{ offset: 1, color: "#FFD16010" },
]),
},
// smooth: true,
},
// {
// data: Array(7)
// .fill(1)
// .map((_) => {
// return randomInt(60, 100);
// }),
// type: "line",
// areaStyle: {
// color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
// { offset: 0, color: "#12FFF540" },
// { offset: 0.5, color: "#12FFF520" },
// { offset: 1, color: "#12FFF510" },
// ]),
// },
// // smooth: true,
// },
// {
// data: Array(7)
// .fill(1)
// .map((_) => {
// return randomInt(60, 100);
// }),
// type: "line",
// areaStyle: {
// color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
// { offset: 0, color: "#2760FF40" },
// { offset: 0.5, color: "#2760FF20" },
// { offset: 1, color: "#2760FF10" },
// ]),
// },
// // smooth: true,
// },
],
tooltip: {
trigger: "axis",
},
};
}

View File

@ -1,23 +1,34 @@
import cls from './index.module.scss';
import Container from '../../Container';
import TechSplitline from '../TechSplitline';
import SmokeTrendChart from './SmokeTrendChart';
import cls from "./index.module.scss";
import Container from "../../Container";
import TechSplitline from "../TechSplitline";
import SmokeTrendChart from "./SmokeTrendChart";
import { useSelector } from "react-redux";
function SmokeHandle(props) {
return (
<Container title="烟气处理" icon="smoke" className={cls.smokeHandle} pending={true}>
<div className={`${cls.smokeHandle__content} flex flex-col`}>
<div className={cls.info__item_groups}>
<div className={cls.info__item}> : 72%</div>
<div className={cls.info__item}>一氧化氮排放浓度:59mg/</div>
<div className={cls.info__item}>二氧化硫排放浓度:59mg/</div>
<div className={cls.info__item}>二氧化氮排放浓度:59mg/</div>
</div>
<TechSplitline />
<SmokeTrendChart />
</div>
</Container>
);
const smokeInfo = useSelector((state) => state.smoke?.info);
return (
<Container title="烟气处理" icon="smoke" className={cls.smokeHandle}>
<div className={`${cls.smokeHandle__content} flex flex-col`}>
<div className={cls.info__item_groups}>
<div className={cls.info__item}>
: {smokeInfo?.O2_float || 0}%
</div>
<div className={cls.info__item}>
氮氧化物浓度: {smokeInfo?.NOX_float || 0}mg/
</div>
<div className={cls.info__item}>
二氧化硫浓度: {smokeInfo?.SO2_float || 0}mg/
</div>
<div className={cls.info__item}>
颗粒物浓度: {smokeInfo?.dust_float || 0}mg/
</div>
</div>
<TechSplitline />
<SmokeTrendChart />
</div>
</Container>
);
}
export default SmokeHandle;

View File

@ -0,0 +1,87 @@
// 风机信息
import { createSlice } from "@reduxjs/toolkit";
export const initialState = {
info: {
SO2_float: 0,
NOX_float: 0,
O2_float: 0,
dust_float: 0,
},
dayTrend: {
SO2_float: [
{
time: "00:00",
value: 10,
},
{ time: "01:00", value: 20 },
],
NOX_float: [],
O2_float: [],
dust_float: [],
},
weekTrend: {
SO2_float: [],
NOX_float: [
{
time: "00:00",
value: 30,
},
{ time: "01:00", value: 10 },
],
O2_float: [],
dust_float: [],
},
monthTrend: {
SO2_float: [],
NOX_float: [],
O2_float: [],
dust_float: [],
},
yearTrend: {
SO2_float: [],
NOX_float: [],
O2_float: [],
dust_float: [
{
time: "00:00",
value: 33,
},
{ time: "01:00", value: 13 },
],
},
};
const smokeSlice = createSlice({
name: "smoke",
initialState,
reducers: {
setInfo: (state, action) => {
state.info = {
...state.info,
...action.payload,
};
},
setTrend: (state, action) => {
state.dayTrend = {
...state.dayTrend,
...action.payload.dayTrend,
};
state.weekTrend = {
...state.weekTrend,
...action.payload.weekTrend,
};
state.monthTrend = {
...state.monthTrend,
...action.payload.monthTrend,
};
state.yearTrend = {
...state.yearTrend,
...action.payload.yearTrend,
};
},
},
});
export default smokeSlice.reducer;
export const { setInfo, setTrend } = smokeSlice.actions;

View File

@ -13,6 +13,7 @@ import israReducer from "./features/QualityIsraSlice";
import annealFanFrequenceReducer from "./features/annealFanFrequenceSlice";
import annealFanInfoReducer from "./features/annealFanInfoSlice";
import cuttingReducer from "./features/cuttingSlice";
import smokeReducer from "./features/smokeSlice";
export const store = configureStore({
reducer: {
@ -43,6 +44,8 @@ export const store = configureStore({
// 能耗
isra: israReducer,
// 切割
cutting: cuttingReducer
cutting: cuttingReducer,
// 烟气
smoke: smokeReducer
},
});

View File

@ -3,6 +3,7 @@ import cuttingHandler from "./cutting";
import energeHandler from "./energe";
import IsHandler from "./IS";
import dcsHandler from "./dcs";
import smokeHandler from "./smoke";
/**
* new XClient('ws://192.168.1.12:8081/xc-screen/websocket/xc001', 'DCS')
@ -66,6 +67,14 @@ new XClient(
cuttingHandler
);
// 烟气处理相关数据
new XClient(
// "ws://10.70.27.122:8080/websocket/message?userId=CUTTING",
"ws://192.168.1.62:48082/websocket/message?userId=" + newUser,
"SMOKE_DATA",
smokeHandler
);
export function randomInt(min: number, max: number, includeMax = false) {
let Fn = includeMax ? Math.ceil : Math.floor;
let num = Fn(Math.random() * max);

21
src/utils/smoke.ts Normal file
View File

@ -0,0 +1,21 @@
import { store } from "../store";
export default function handler(msg: MessageEvent) {
let serializedData: { type: string; data: any } | null = null;
try {
serializedData = JSON.parse(msg.data);
} catch (error) {
console.log("[*] websocket: [unable to serialize] ---> ", msg);
}
switch (serializedData?.type) {
case "exhaustGas": {
store.dispatch("smoke/setInfo", serializedData.data.realtime);
store.dispatch("smoke/setTrend", serializedData.data);
break;
}
default: {
console.log("websocket message: [unknown] ---> ", msg.data);
}
}
}