update烟气
This commit is contained in:
parent
4e73410495
commit
049a0804ac
@ -1,162 +1,70 @@
|
|||||||
import cls from './index.module.css';
|
import cls from "./index.module.css";
|
||||||
import { randomInt } from '../../../../utils';
|
import { randomInt } from "../../../../utils";
|
||||||
|
import * as echarts from "echarts";
|
||||||
import * as echarts from 'echarts';
|
import { Radio } from "antd";
|
||||||
import { Switch, Radio } from 'antd';
|
import ReactECharts from "echarts-for-react";
|
||||||
import ReactECharts from 'echarts-for-react';
|
import { useState } from "react";
|
||||||
|
import { useSelector } from "react-redux";
|
||||||
|
|
||||||
const SmokeTrendChart = (props) => {
|
const SmokeTrendChart = (props) => {
|
||||||
const options = {
|
const dayTrend = useSelector((state) => state.smoke?.dayTrend);
|
||||||
color: ['#FFD160', '#12FFF5', '#2760FF'],
|
const weekTrend = useSelector((state) => state.smoke?.weekTrend);
|
||||||
grid: { top: 38, right: 12, bottom: 20, left: 48 },
|
const monthTrend = useSelector((state) => state.smoke?.monthTrend);
|
||||||
xAxis: {
|
const yearTrend = useSelector((state) => state.smoke?.yearTrend);
|
||||||
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',
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
function handleSwitchChange(val) {
|
const [source, setSource] = useState("O2_float");
|
||||||
// val: boolean
|
const [period, setPeriod] = useState("day");
|
||||||
}
|
|
||||||
|
const currentTrend =
|
||||||
|
period === "day"
|
||||||
|
? dayTrend
|
||||||
|
: period === "week"
|
||||||
|
? weekTrend
|
||||||
|
: period === "month"
|
||||||
|
? monthTrend
|
||||||
|
: yearTrend;
|
||||||
|
|
||||||
|
const options = getOptions(source, period, currentTrend);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={cls.energyCostChart}>
|
<div className={cls.energyCostChart}>
|
||||||
<div className={cls.titleBar}>
|
<div className={cls.titleBar}>
|
||||||
<h2>烟气趋势图</h2>
|
<h2>烟气趋势图</h2>
|
||||||
<Switch defaultChecked onChange={handleSwitchChange} />
|
{/* <Switch defaultChecked onChange={handleSwitchChange} /> */}
|
||||||
<div className={cls.legend}>
|
{/* <div className={cls.legend}>
|
||||||
<span className="legend__title">班次详情</span>
|
<span className="legend__title">班次详情</span>
|
||||||
<ul className="legend__list">
|
<ul className="legend__list">
|
||||||
<li>总量</li>
|
<li>总量</li>
|
||||||
<li>白班</li>
|
<li>白班</li>
|
||||||
<li>夜班</li>
|
<li>夜班</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div> */}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className={`${cls.choiceBar} flex items-center justify-between`}>
|
<div className={`${cls.choiceBar} flex items-center justify-between`}>
|
||||||
<Radio.Group
|
<Radio.Group
|
||||||
defaultValue="oxygen"
|
value={source}
|
||||||
|
onChange={(e) => setSource(e.target.value)}
|
||||||
buttonStyle="solid"
|
buttonStyle="solid"
|
||||||
className={`${cls.radioGroup} flex items-center justify-between`}
|
className={`${cls.radioGroup} flex items-center justify-between`}
|
||||||
>
|
>
|
||||||
<Radio.Button value="oxygen" className="radio-group__item">
|
<Radio.Button value="O2_float" className="radio-group__item">
|
||||||
氧气含量
|
氧气
|
||||||
</Radio.Button>
|
</Radio.Button>
|
||||||
<Radio.Button value="so2" className="radio-group__item">
|
<Radio.Button value="NOX_float" className="radio-group__item">
|
||||||
|
氮氧化物
|
||||||
|
</Radio.Button>
|
||||||
|
<Radio.Button value="SO2_float" className="radio-group__item">
|
||||||
二氧化硫
|
二氧化硫
|
||||||
</Radio.Button>
|
</Radio.Button>
|
||||||
<Radio.Button value="no" className="radio-group__item">
|
<Radio.Button value="dust_float" className="radio-group__item">
|
||||||
一氧化氮
|
颗粒物
|
||||||
</Radio.Button>
|
|
||||||
<Radio.Button value="no2" className="radio-group__item">
|
|
||||||
二氧化氮
|
|
||||||
</Radio.Button>
|
</Radio.Button>
|
||||||
</Radio.Group>
|
</Radio.Group>
|
||||||
|
|
||||||
<Radio.Group
|
<Radio.Group
|
||||||
defaultValue="week"
|
value={period}
|
||||||
|
onChange={(e) => setPeriod(e.target.value)}
|
||||||
buttonStyle="solid"
|
buttonStyle="solid"
|
||||||
className={cls.radioGroup}
|
className={cls.radioGroup}
|
||||||
>
|
>
|
||||||
@ -174,9 +82,118 @@ const SmokeTrendChart = (props) => {
|
|||||||
</Radio.Button>
|
</Radio.Button>
|
||||||
</Radio.Group>
|
</Radio.Group>
|
||||||
</div>
|
</div>
|
||||||
<ReactECharts option={options} style={{ height: '240px' }} />
|
<ReactECharts option={options} style={{ height: "240px" }} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default SmokeTrendChart;
|
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",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
@ -1,17 +1,28 @@
|
|||||||
import cls from './index.module.scss';
|
import cls from "./index.module.scss";
|
||||||
import Container from '../../Container';
|
import Container from "../../Container";
|
||||||
import TechSplitline from '../TechSplitline';
|
import TechSplitline from "../TechSplitline";
|
||||||
import SmokeTrendChart from './SmokeTrendChart';
|
import SmokeTrendChart from "./SmokeTrendChart";
|
||||||
|
import { useSelector } from "react-redux";
|
||||||
|
|
||||||
function SmokeHandle(props) {
|
function SmokeHandle(props) {
|
||||||
|
const smokeInfo = useSelector((state) => state.smoke?.info);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container title="烟气处理" icon="smoke" className={cls.smokeHandle} pending={true}>
|
<Container title="烟气处理" icon="smoke" className={cls.smokeHandle}>
|
||||||
<div className={`${cls.smokeHandle__content} flex flex-col`}>
|
<div className={`${cls.smokeHandle__content} flex flex-col`}>
|
||||||
<div className={cls.info__item_groups}>
|
<div className={cls.info__item_groups}>
|
||||||
<div className={cls.info__item}>氧 气 含 量 : 72%</div>
|
<div className={cls.info__item}>
|
||||||
<div className={cls.info__item}>一氧化氮排放浓度:59mg/m³</div>
|
氧 气 含 量 : {smokeInfo?.O2_float || 0}%
|
||||||
<div className={cls.info__item}>二氧化硫排放浓度:59mg/m³</div>
|
</div>
|
||||||
<div className={cls.info__item}>二氧化氮排放浓度:59mg/m³</div>
|
<div className={cls.info__item}>
|
||||||
|
氮氧化物浓度: {smokeInfo?.NOX_float || 0}mg/m³
|
||||||
|
</div>
|
||||||
|
<div className={cls.info__item}>
|
||||||
|
二氧化硫浓度: {smokeInfo?.SO2_float || 0}mg/m³
|
||||||
|
</div>
|
||||||
|
<div className={cls.info__item}>
|
||||||
|
颗粒物浓度: {smokeInfo?.dust_float || 0}mg/m³
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<TechSplitline />
|
<TechSplitline />
|
||||||
<SmokeTrendChart />
|
<SmokeTrendChart />
|
||||||
|
87
src/store/features/smokeSlice.js
Normal file
87
src/store/features/smokeSlice.js
Normal 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;
|
@ -13,6 +13,7 @@ import israReducer from "./features/QualityIsraSlice";
|
|||||||
import annealFanFrequenceReducer from "./features/annealFanFrequenceSlice";
|
import annealFanFrequenceReducer from "./features/annealFanFrequenceSlice";
|
||||||
import annealFanInfoReducer from "./features/annealFanInfoSlice";
|
import annealFanInfoReducer from "./features/annealFanInfoSlice";
|
||||||
import cuttingReducer from "./features/cuttingSlice";
|
import cuttingReducer from "./features/cuttingSlice";
|
||||||
|
import smokeReducer from "./features/smokeSlice";
|
||||||
|
|
||||||
export const store = configureStore({
|
export const store = configureStore({
|
||||||
reducer: {
|
reducer: {
|
||||||
@ -43,6 +44,8 @@ export const store = configureStore({
|
|||||||
// 能耗
|
// 能耗
|
||||||
isra: israReducer,
|
isra: israReducer,
|
||||||
// 切割
|
// 切割
|
||||||
cutting: cuttingReducer
|
cutting: cuttingReducer,
|
||||||
|
// 烟气
|
||||||
|
smoke: smokeReducer
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
@ -3,6 +3,7 @@ import cuttingHandler from "./cutting";
|
|||||||
import energeHandler from "./energe";
|
import energeHandler from "./energe";
|
||||||
import IsHandler from "./IS";
|
import IsHandler from "./IS";
|
||||||
import dcsHandler from "./dcs";
|
import dcsHandler from "./dcs";
|
||||||
|
import smokeHandler from "./smoke";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* new XClient('ws://192.168.1.12:8081/xc-screen/websocket/xc001', 'DCS')
|
* new XClient('ws://192.168.1.12:8081/xc-screen/websocket/xc001', 'DCS')
|
||||||
@ -66,6 +67,14 @@ new XClient(
|
|||||||
cuttingHandler
|
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) {
|
export function randomInt(min: number, max: number, includeMax = false) {
|
||||||
let Fn = includeMax ? Math.ceil : Math.floor;
|
let Fn = includeMax ? Math.ceil : Math.floor;
|
||||||
let num = Fn(Math.random() * max);
|
let num = Fn(Math.random() * max);
|
||||||
|
21
src/utils/smoke.ts
Normal file
21
src/utils/smoke.ts
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user