Compare commits
No commits in common. "master" and "testing-redux" have entirely different histories.
master
...
testing-re
12381
package-lock.json
generated
12381
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -3,7 +3,6 @@
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@ant-design/icons": "^5.2.6",
|
||||
"@babel/core": "^7.16.0",
|
||||
"@jiaminghi/data-view-react": "^1.2.5",
|
||||
"@pmmmwh/react-refresh-webpack-plugin": "^0.5.3",
|
||||
@ -23,7 +22,6 @@
|
||||
"case-sensitive-paths-webpack-plugin": "^2.4.0",
|
||||
"css-loader": "^6.5.1",
|
||||
"css-minimizer-webpack-plugin": "^3.2.0",
|
||||
"dayjs": "^1.11.10",
|
||||
"dotenv": "^10.0.0",
|
||||
"dotenv-expand": "^5.1.0",
|
||||
"echarts": "^5.4.3",
|
||||
@ -61,7 +59,6 @@
|
||||
"style-loader": "^3.3.1",
|
||||
"tailwindcss": "^3.0.2",
|
||||
"terser-webpack-plugin": "^5.2.5",
|
||||
"uuid": "^9.0.1",
|
||||
"webpack": "^5.64.4",
|
||||
"webpack-dev-server": "^4.6.0",
|
||||
"webpack-manifest-plugin": "^4.0.2",
|
||||
@ -92,10 +89,8 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/plugin-proposal-private-property-in-object": "^7.21.11",
|
||||
"@types/uuid": "^9.0.7",
|
||||
"less": "^4.2.0",
|
||||
"less-loader": "^11.1.3",
|
||||
"typescript": "^5.3.3"
|
||||
"less-loader": "^11.1.3"
|
||||
},
|
||||
"jest": {
|
||||
"roots": [
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
53
src/App.js
53
src/App.js
@ -1,68 +1,27 @@
|
||||
// import "./App.css";
|
||||
import "./global.css";
|
||||
import "./index.css";
|
||||
import Head from "./components/Common/Company";
|
||||
// import { SocketContextProvider } from "../store/socket-data-provider";
|
||||
import useSlider, { Slider } from "./hooks/useSlider";
|
||||
import NavMenu from "./components/Common/NavMenu";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useState } from "react";
|
||||
import Home from "./pages/Home";
|
||||
import EnergyAnalysis from "./pages/EnergyCostAnalysis";
|
||||
import RulerContainer from "./components/Tools/Ruler";
|
||||
import { Switch } from "antd";
|
||||
import { createPortal } from "react-dom";
|
||||
|
||||
const Menus = ["窑炉总览", "窑炉内部", "退火监测", "质检统计", "能耗分析"];
|
||||
|
||||
function App() {
|
||||
const { styles, value, setValue } = useSlider(100);
|
||||
const [navActive, setNavActive] = useState("窑炉总览");
|
||||
const [lunbo, setlunbo] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
let timer;
|
||||
if (lunbo) {
|
||||
timer = setInterval(() => {
|
||||
handleMenuChange(Menus[(Menus.indexOf(navActive) + 1) % Menus.length]);
|
||||
}, 5000);
|
||||
}
|
||||
return () => {
|
||||
clearInterval(timer);
|
||||
};
|
||||
}, [lunbo, navActive]);
|
||||
|
||||
function handleSwitchChange(val) {
|
||||
setlunbo(val);
|
||||
}
|
||||
|
||||
function handleMenuChange(value) {
|
||||
setNavActive(value);
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<div id="FullScreen" style={{ ...styles, overflow: "hidden" }}>
|
||||
<NavMenu active={navActive} onChangeActive={handleMenuChange} />
|
||||
<div id="FullScreen" style={styles}>
|
||||
<NavMenu active={navActive} onChangeActive={(v) => setNavActive(v)} />
|
||||
<Head />
|
||||
<div
|
||||
className="lunbo-setting"
|
||||
style={{
|
||||
position: "fixed",
|
||||
top: "48px",
|
||||
right: "680px",
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
gap: "16px",
|
||||
}}
|
||||
>
|
||||
<span style={{ fontSize: "20px", color: "#00fff7" }}>模块轮播</span>
|
||||
<Switch
|
||||
className="lunbo-btn"
|
||||
size="small"
|
||||
value={lunbo}
|
||||
onChange={handleSwitchChange}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{navActive == "能耗分析" && <EnergyAnalysis />}
|
||||
{navActive == "能耗分析" && <div className="bgDitu"></div>}
|
||||
{navActive != "能耗分析" && <Home active={navActive} />}
|
||||
</div>
|
||||
<Slider value={value} setValue={setValue} />
|
||||
|
@ -1,14 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<title>温度</title>
|
||||
<g id="退火监测" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g transform="translate(-64.000000, -134.000000)" fill-rule="nonzero" id="编组-8备份">
|
||||
<g transform="translate(40.000000, 112.000000)">
|
||||
<g id="温度" transform="translate(24.000000, 22.000000)">
|
||||
<rect id="矩形" fill="#000000" opacity="0" x="0" y="0" width="24" height="24"></rect>
|
||||
<path d="M18.6,15 C18.15,14.25 17.4,13.5 16.5,13.05 L16.5,3 C16.5,1.35 15.3,0 13.65,0 C12,0 10.8,1.35 10.8,3 L10.8,13.2 C9.9,13.5 9.3,14.25 8.7,15 C8.1,15.9 7.8,16.95 7.8,18.15 C7.8,19.65 8.4,21.15 9.45,22.2 C10.5,23.25 12.15,24 13.65,24 C15.15,24 16.65,23.4 17.7,22.35 C18.75,21.3 19.35,19.8 19.35,18.3 C19.5,17.1 19.2,16.05 18.6,15 Z M13.65,22.95 C10.95,22.95 8.85,20.7 8.85,18.15 C8.85,16.35 9.9,14.7 11.55,13.8 L11.85,13.65 L11.85,3 C11.85,1.95 12.75,1.05 13.8,1.05 C14.85,1.05 15.75,1.95 15.75,3 L15.75,13.8 L16.05,13.95 C17.7,14.85 18.75,16.5 18.75,18.3 C18.6,20.85 16.35,22.95 13.65,22.95 Z M14.55,15.6 L14.55,6.15 C14.55,5.7 14.1,5.25 13.65,5.25 C13.2,5.25 12.75,5.7 12.75,6.15 L12.75,15.6 C11.7,15.9 11.1,16.95 11.1,18 C11.1,19.35 12.3,20.55 13.65,20.55 C15,20.55 16.2,19.35 16.2,18 C16.2,16.95 15.6,15.9 14.55,15.6 Z M8.25,4.35 L3.6,4.35 C3,4.35 2.7,4.05 2.7,3.45 C2.7,3 3,2.55 3.6,2.55 L8.4,2.55 C8.85,2.55 9.3,3 9.3,3.45 C9.15,4.05 8.85,4.35 8.25,4.35 L8.25,4.35 Z M8.25,7.2 L5.25,7.2 C4.8,7.2 4.35,6.75 4.35,6.3 C4.35,5.85 4.8,5.4 5.25,5.4 L8.25,5.4 C8.7,5.4 9.15,5.85 9.15,6.3 C9.15,6.9 8.85,7.2 8.25,7.2 Z M8.25,10.2 L7.35,10.2 C6.9,10.2 6.45,9.75 6.45,9.3 C6.45,8.85 6.9,8.4 7.35,8.4 L8.4,8.4 C8.85,8.4 9.3,8.85 9.3,9.3 C9.15,9.75 8.85,10.2 8.25,10.2 Z" id="形状" fill="#59D0E2"></path>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
Before Width: | Height: | Size: 2.0 KiB |
@ -1,14 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="16px" height="16px" viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<title>编组 13</title>
|
||||
<g id="·窑炉总览" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="总览" transform="translate(-1823.000000, -772.000000)">
|
||||
<g id="编组-20备份-5" transform="translate(1786.000000, 764.000000)">
|
||||
<g id="编组-13" transform="translate(45.000000, 16.000000) scale(1, -1) rotate(-180.000000) translate(-45.000000, -16.000000) translate(37.000000, 8.000000)">
|
||||
<rect id="矩形" stroke="#979797" fill="#D8D8D8" opacity="0" x="0.5" y="0.5" width="15" height="15"></rect>
|
||||
<path d="M3.67840479,4.47768215 L12.3215952,4.47768215 C12.87388,4.47768215 13.3215952,4.9253974 13.3215952,5.47768215 C13.3215952,5.70423387 13.2446673,5.92407165 13.1034098,6.1011931 L8.78181462,11.5200015 C8.43745903,11.9517857 7.80827335,12.0226607 7.37648905,11.6783051 C7.31796217,11.6316289 7.2648616,11.5785283 7.21818538,11.5200015 L2.89659016,6.1011931 C2.55223458,5.6694088 2.62310955,5.04022312 3.05489384,4.69586753 C3.23201529,4.55461005 3.45185307,4.47768215 3.67840479,4.47768215 Z" id="路径-2" fill="#03233C"></path>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
Before Width: | Height: | Size: 1.4 KiB |
Binary file not shown.
Before Width: | Height: | Size: 7.5 MiB After Width: | Height: | Size: 2.7 MiB |
Binary file not shown.
Before Width: | Height: | Size: 13 KiB |
Binary file not shown.
Before Width: | Height: | Size: 13 KiB |
@ -1,5 +0,0 @@
|
||||
function AmenSelector() {
|
||||
return <div className="amen-selector"></div>;
|
||||
}
|
||||
|
||||
export default AmenSelector;
|
@ -1,212 +0,0 @@
|
||||
// AnnealFanRunFrequence
|
||||
import cls from "./index.module.css";
|
||||
import * as echarts from "echarts";
|
||||
import GraphBase from "../GraphBase";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useSelector } from "react-redux";
|
||||
|
||||
function WindFrequence(props) {
|
||||
const [currLine, setCurrLine] = useState('Y61')
|
||||
const [showChart, setShowChart] = useState(false);
|
||||
const [currentLine, setCurrentLine] = useState([]);
|
||||
const runState = useSelector((state) => state.annealFanFrequence.runtime);
|
||||
const hisState = useSelector((state) => state.annealFanFrequence.history);
|
||||
|
||||
let dataList = [];
|
||||
let seriesData = [];
|
||||
const colors = [
|
||||
"#12FFF5",
|
||||
"#2760FF",
|
||||
"#FFD160",
|
||||
"#E80091",
|
||||
"#8064ff",
|
||||
"#ff8a3b",
|
||||
"#8cd26d",
|
||||
"#2aa1ff",
|
||||
];
|
||||
let options = null;
|
||||
if (showChart) {
|
||||
// keys() 结果不是按照顺序,需要 sort()
|
||||
seriesData =
|
||||
hisState != null
|
||||
? Object.keys(hisState)
|
||||
.sort()
|
||||
.map((key) => hisState[key])
|
||||
: Array(8)
|
||||
.fill(1)
|
||||
.map((_) => Array(7).fill(0));
|
||||
|
||||
options = {
|
||||
color: colors,
|
||||
grid: { top: 32, 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³",
|
||||
nameTextStyle: {
|
||||
color: "#fff",
|
||||
fontSize: 10,
|
||||
align: "right",
|
||||
},
|
||||
type: "value",
|
||||
axisLabel: {
|
||||
color: "#fff",
|
||||
fontSize: 12,
|
||||
},
|
||||
axisLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
color: "#213259",
|
||||
},
|
||||
},
|
||||
splitLine: {
|
||||
lineStyle: {
|
||||
color: "#213259a0",
|
||||
},
|
||||
},
|
||||
// interval: 10,
|
||||
// min: 0,
|
||||
// max: 100,
|
||||
},
|
||||
series: seriesData.map((v, i) => ({
|
||||
name: i + 1 + "#风机",
|
||||
data: v,
|
||||
type: "line",
|
||||
symbol: "circle",
|
||||
areaStyle: {
|
||||
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
||||
// i % 8 避免超过8个数据时无颜色的问题
|
||||
{ offset: 0, color: colors[i % 8] + "40" },
|
||||
{ offset: 0.5, color: colors[i % 8] + "20" },
|
||||
{ offset: 1, color: colors[i % 8] + "00" },
|
||||
]),
|
||||
},
|
||||
})),
|
||||
tooltip: {
|
||||
trigger: "axis",
|
||||
},
|
||||
};
|
||||
} else {
|
||||
dataList =
|
||||
runState != null
|
||||
? Object.keys(runState).map((fan) => ({
|
||||
id: Math.random(),
|
||||
name: fan,
|
||||
value: runState[fan],
|
||||
}))
|
||||
: [
|
||||
{ id: 1, name: "1#风机#1", value: "0m³/h" },
|
||||
// { id: 133, name: "1#风机#1", value: "0m³/h" },
|
||||
// { id: 134, name: "1#风机#1", value: "0m³/h" },
|
||||
// { id: 1344, name: "1#风机#1", value: "0m³/h" },
|
||||
// { id: 51, name: "1#风机#1", value: "0m³/h" },
|
||||
// { id: 1534, name: "1#风机#1", value: "0m³/h" },
|
||||
// { id: 154, name: "1#风机#1", value: "0m³/h" },
|
||||
// { id: 153, name: "1#风机#1", value: "0m³/h" },
|
||||
// { id: 111, name: "1#风机#1", value: "0m³/h" },
|
||||
{ id: 2, name: "2#风机#1", value: "0m³/h" },
|
||||
{ id: 3, name: "3#风机#1", value: "0m³/h" },
|
||||
{ id: 4, name: "4#风机#1", value: "0m³/h" },
|
||||
{ id: 5, name: "5#风机#1", value: "0m³/h" },
|
||||
{ id: 11, name: "1#风机#2", value: "0m³/h" },
|
||||
{ id: 12, name: "2#风机#2", value: "0m³/h" },
|
||||
{ id: 13, name: "3#风机#2", value: "0m³/h" },
|
||||
{ id: 14, name: "4#风机#2", value: "0m³/h" },
|
||||
{ id: 15, name: "5#风机#2", value: "0m³/h" },
|
||||
];
|
||||
}
|
||||
|
||||
function handleSwitchChange(val) {
|
||||
if (val) {
|
||||
setShowChart(true);
|
||||
} else {
|
||||
setShowChart(false);
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (!showChart) {
|
||||
setCurrentLine((old) =>
|
||||
dataList.filter((item) => item?.name.startsWith("1#"))
|
||||
);
|
||||
}
|
||||
}, [showChart]);
|
||||
|
||||
function handleLineChange(line) {
|
||||
const lineNum = line[2];
|
||||
setCurrLine(line);
|
||||
setCurrentLine((old) =>
|
||||
dataList.filter((item) => item?.name.startsWith(`${lineNum}#`))
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<GraphBase
|
||||
icon="kiln"
|
||||
title="风机运行频率"
|
||||
size={["middle", "long"]}
|
||||
switchOptions={false}
|
||||
switchPosition={[null, 200]} // [top, left]
|
||||
onSwitch={handleSwitchChange}
|
||||
dateOptions={["Y61", "Y62", "Y63", "Y64", "Y65"]}
|
||||
selectWidth={70}
|
||||
defaultSelect={currLine}
|
||||
onDateChange={handleLineChange}
|
||||
>
|
||||
<div className={cls.chart} style={{ marginTop: "24px" }}>
|
||||
{/* {showChart && (
|
||||
<ReactECharts option={options} style={{ height: "100%" }} />
|
||||
)} */}
|
||||
{!showChart && (
|
||||
<div className={cls.gridList}>
|
||||
{currentLine.map((item) => (
|
||||
<div
|
||||
key={item.id}
|
||||
className={cls.listItem}
|
||||
style={{ padding: props.stretch ? "20px 0" : "" }}
|
||||
>
|
||||
<span className={cls.fanName}>{item.name}</span>
|
||||
<span
|
||||
className={cls.fanValue}
|
||||
style={{
|
||||
fontWeight: 700,
|
||||
letterSpacing: 1,
|
||||
fontSize: 16,
|
||||
// color: "#e03537",
|
||||
color: "#24aebb",
|
||||
}}
|
||||
>
|
||||
{item.value}
|
||||
</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</GraphBase>
|
||||
);
|
||||
}
|
||||
|
||||
export default WindFrequence;
|
@ -1,52 +0,0 @@
|
||||
.chart {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.gridList {
|
||||
margin-top: 12px;
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
/* grid-auto-row: ; */
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.listItem {
|
||||
border-radius: 2px;
|
||||
padding: 10px 0;
|
||||
text-align: center;
|
||||
color: #fff;
|
||||
box-shadow: inset 0 0 16px 4px rgba(255, 255, 255, 0.197);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.headWidget {
|
||||
position: absolute;
|
||||
top: 22px;
|
||||
right: 24px;
|
||||
height: 32px;
|
||||
width: 410px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
color: #fff;
|
||||
}
|
||||
.relative {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.flex {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.fanName {
|
||||
text-align: right;
|
||||
flex: 7;
|
||||
}
|
||||
|
||||
.fanValue {
|
||||
flex: 3;
|
||||
text-align: left;
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
import cls from "./index.module.css";
|
||||
|
||||
const Arrow = ({ direction, disabled, onClick }) => {
|
||||
function handleClick() {
|
||||
onClick(direction)
|
||||
}
|
||||
return (
|
||||
<button
|
||||
className={`${cls["arrow"]} ${
|
||||
direction == "right" ? cls["arrow__right"] : ""
|
||||
} ${true ? "disabled" : ""}`}
|
||||
onClick={handleClick}
|
||||
>
|
||||
<div
|
||||
className={`${cls["arrow-top"]} ${
|
||||
direction == "right" ? cls["arrow-top__right"] : ""
|
||||
}`}
|
||||
></div>
|
||||
<div
|
||||
className={`${cls["arrow-bottom"]} ${
|
||||
direction == "right" ? cls["arrow-bottom__right"] : ""
|
||||
}`}
|
||||
></div>
|
||||
</button>
|
||||
);
|
||||
};
|
||||
|
||||
export default Arrow;
|
@ -1,60 +0,0 @@
|
||||
|
||||
|
||||
.arrow {
|
||||
appearance: none;
|
||||
outline: none;
|
||||
border: none;
|
||||
background: transparent;
|
||||
width: 16px;
|
||||
height: 48px;
|
||||
position: absolute;
|
||||
top: 112px;
|
||||
left: 5px;
|
||||
cursor: pointer;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.arrow.disabled > div {
|
||||
background: #3d4a56;
|
||||
}
|
||||
|
||||
.arrow__right {
|
||||
left: unset;
|
||||
right: 5px;
|
||||
}
|
||||
|
||||
.arrow:hover > div {
|
||||
background: #00f3ed;
|
||||
}
|
||||
|
||||
.arrow-top {
|
||||
transition: background 0.1s ease-out;
|
||||
background: #1eaba9;
|
||||
width: 8px;
|
||||
height: 24px;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
border-radius: 12px;
|
||||
transform: rotateZ(20deg) translateY(2px) translateX(4px);
|
||||
}
|
||||
|
||||
.arrow-bottom {
|
||||
transition: background 0.1s ease-out;
|
||||
background: #1eaba9;
|
||||
width: 8px;
|
||||
height: 24px;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
border-radius: 12px;
|
||||
transform: rotateZ(-20deg) translateY(-2px) translateX(4px);
|
||||
}
|
||||
|
||||
.arrow-top__right {
|
||||
transform: rotateZ(-20deg) translateY(4px) translateX(4px);
|
||||
}
|
||||
|
||||
.arrow-bottom__right {
|
||||
transform: rotateZ(20deg) translateY(-4px) translateX(4px);
|
||||
}
|
@ -1,32 +0,0 @@
|
||||
import cls from "./index.module.css";
|
||||
|
||||
function BlueRect(props) {
|
||||
const title = props.title || "DEFAULT";
|
||||
const value = props.value || "0℃";
|
||||
return (
|
||||
<div
|
||||
className={`${cls.blueRect} ${cls[title]}`}
|
||||
style={{
|
||||
background: props.blue ? "#0a4268ee" : "#0a426860",
|
||||
}}
|
||||
>
|
||||
<span
|
||||
className="title"
|
||||
style={{
|
||||
fontSize: "18px",
|
||||
lineHeight: "24px",
|
||||
color: props.blue ? "#40afb8" : "#fff",
|
||||
fontWeight: 600,
|
||||
userSelect: "none",
|
||||
}}
|
||||
>
|
||||
{title}
|
||||
</span>
|
||||
<span className="value" style={{ userSelect: "none", fontSize: "22px" }}>
|
||||
{value}
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default BlueRect;
|
@ -1,544 +0,0 @@
|
||||
.blueRect {
|
||||
display: inline-block;
|
||||
width: 106px;
|
||||
height: 68px;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
padding: 6px 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
color: #fff;
|
||||
background: #0a426820;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.blueRect::before {
|
||||
content: "";
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 3px;
|
||||
background: linear-gradient(
|
||||
to right,
|
||||
transparent 0%,
|
||||
transparent 50%,
|
||||
#24aebb 100%
|
||||
);
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.blueRect::after {
|
||||
content: "";
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 3px;
|
||||
background: linear-gradient(
|
||||
to right,
|
||||
#24aebb 0%,
|
||||
transparent 50%,
|
||||
transparent 100%
|
||||
);
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
/** left **/
|
||||
|
||||
.TE271 {
|
||||
top: 160px;
|
||||
left: 70px;
|
||||
}
|
||||
.TE272 {
|
||||
top: 254px; /* +94px */
|
||||
left: 70px;
|
||||
}
|
||||
.TE273 {
|
||||
top: 348px; /* +94px */
|
||||
left: 70px;
|
||||
}
|
||||
.TE274 {
|
||||
top: 442px;
|
||||
left: 70px;
|
||||
}
|
||||
.TE279 {
|
||||
top: 536px;
|
||||
left: 70px;
|
||||
}
|
||||
.TE275 {
|
||||
top: 160px;
|
||||
left: 206px;
|
||||
}
|
||||
.TE276 {
|
||||
top: 254px;
|
||||
left: 206px; /* +136px */
|
||||
}
|
||||
.TE277 {
|
||||
top: 348px; /* +94px */
|
||||
left: 206px; /* +136px */
|
||||
}
|
||||
.TE278 {
|
||||
top: 442px; /* +94px */
|
||||
left: 206px; /* +136px */
|
||||
}
|
||||
.TE280 {
|
||||
top: 536px; /* +94px */
|
||||
left: 206px; /* +136px */
|
||||
}
|
||||
|
||||
/** center top **/
|
||||
.TE227 {
|
||||
top: 128px;
|
||||
left: 630px;
|
||||
}
|
||||
.TE229 {
|
||||
top: 128px;
|
||||
left: 746px; /* +120px */
|
||||
}
|
||||
.TE231 {
|
||||
top: 128px;
|
||||
left: 866px;
|
||||
}
|
||||
.TE233 {
|
||||
top: 128px;
|
||||
left: 980px;
|
||||
}
|
||||
.TE235 {
|
||||
top: 128px;
|
||||
left: 1100px;
|
||||
}
|
||||
.TE237 {
|
||||
top: 128px;
|
||||
left: 1220px;
|
||||
}
|
||||
.TE239 {
|
||||
top: 128px;
|
||||
left: 1330px;
|
||||
}
|
||||
.TE241 {
|
||||
top: 128px;
|
||||
left: 1450px;
|
||||
}
|
||||
|
||||
/** center bottom **/
|
||||
.TE228 {
|
||||
top: 620px;
|
||||
left: 600px;
|
||||
}
|
||||
.TE230 {
|
||||
top: 620px;
|
||||
left: 720px;
|
||||
}
|
||||
.TE232 {
|
||||
top: 620px;
|
||||
left: 850px;
|
||||
}
|
||||
.TE234 {
|
||||
top: 620px;
|
||||
left: 970px;
|
||||
}
|
||||
.TE236 {
|
||||
top: 620px;
|
||||
left: 1100px;
|
||||
}
|
||||
.TE238 {
|
||||
top: 620px;
|
||||
left: 1225px;
|
||||
}
|
||||
.TE240 {
|
||||
top: 620px;
|
||||
left: 1350px;
|
||||
}
|
||||
.TE242 {
|
||||
top: 620px;
|
||||
left: 1470px;
|
||||
}
|
||||
|
||||
/** center middle **/
|
||||
.TE201 {
|
||||
top: 410px;
|
||||
/* transform: rotate(-1deg); */
|
||||
left: 480px;
|
||||
}
|
||||
.TE202 {
|
||||
top: 410px;
|
||||
/* transform: rotate(-1deg); */
|
||||
left: 610px;
|
||||
}
|
||||
.TE203 {
|
||||
top: 410px;
|
||||
/* transform: rotate(-1deg); */
|
||||
left: 740px;
|
||||
}
|
||||
.TE204 {
|
||||
top: 410px;
|
||||
/* transform: rotate(-1deg); */
|
||||
left: 870px;
|
||||
}
|
||||
.TE205 {
|
||||
top: 410px;
|
||||
/* transform: rotate(-1deg); */
|
||||
left: 1000px;
|
||||
}
|
||||
.TE206 {
|
||||
top: 410px;
|
||||
/* transform: rotate(-1deg); */
|
||||
left: 1130px;
|
||||
}
|
||||
.TE207 {
|
||||
top: 330px;
|
||||
/* transform: rotate(-1deg); */
|
||||
left: 1260px;
|
||||
}
|
||||
.TE208 {
|
||||
top: 410px;
|
||||
/* transform: rotate(-1deg); */
|
||||
left: 1260px;
|
||||
}
|
||||
.TE209 {
|
||||
top: 485px;
|
||||
/* transform: rotate(-1deg); */
|
||||
left: 1260px;
|
||||
}
|
||||
.TE210 {
|
||||
top: 410px;
|
||||
/* transform: rotate(-1deg); */
|
||||
left: 1390px;
|
||||
}
|
||||
.TE211 {
|
||||
top: 410px;
|
||||
/* transform: rotate(-1deg); */
|
||||
left: 1520px;
|
||||
}
|
||||
.TE212 {
|
||||
top: 410px;
|
||||
/* transform: rotate(-1deg); */
|
||||
left: 1650px;
|
||||
}
|
||||
.TE213 {
|
||||
top: 410px;
|
||||
/* transform: rotate(-1deg); */
|
||||
left: 1780px;
|
||||
}
|
||||
|
||||
/** right **/
|
||||
.TE214 {
|
||||
top: 168px;
|
||||
left: 2000px;
|
||||
}
|
||||
.TE215 {
|
||||
top: 265px;
|
||||
left: 2030px;
|
||||
}
|
||||
.TE216 {
|
||||
top: 400px;
|
||||
left: 2050px;
|
||||
}
|
||||
.TE217 {
|
||||
top: 520px;
|
||||
left: 2070px;
|
||||
}
|
||||
.TE218 {
|
||||
top: 660px;
|
||||
left: 2090px;
|
||||
}
|
||||
.TE219 {
|
||||
top: 168px;
|
||||
left: 2120px;
|
||||
}
|
||||
.TE220 {
|
||||
top: 265px;
|
||||
left: 2135px;
|
||||
}
|
||||
.TE221 {
|
||||
top: 400px;
|
||||
left: 2170px;
|
||||
}
|
||||
.TE222 {
|
||||
top: 520px;
|
||||
left: 2180px;
|
||||
}
|
||||
.TE223 {
|
||||
top: 660px;
|
||||
left: 2200px;
|
||||
}
|
||||
.TE224 {
|
||||
top: 265px;
|
||||
left: 2240px;
|
||||
}
|
||||
.TE225 {
|
||||
top: 400px;
|
||||
left: 2290px;
|
||||
}
|
||||
.TE226 {
|
||||
top: 520px;
|
||||
left: 2290px;
|
||||
}
|
||||
|
||||
/** 一层 --- 窑底 **/
|
||||
.TE401 {
|
||||
top: 420px;
|
||||
left: 20px;
|
||||
}
|
||||
.TE402 {
|
||||
top: 420px;
|
||||
left: 140px;
|
||||
}
|
||||
.TE403 {
|
||||
top: 420px;
|
||||
left: 260px;
|
||||
}
|
||||
.PE401 {
|
||||
top: 320px;
|
||||
left: 20px;
|
||||
}
|
||||
.PE402 {
|
||||
top: 320px;
|
||||
left: 140px;
|
||||
}
|
||||
.PE403 {
|
||||
top: 320px;
|
||||
left: 260px;
|
||||
}
|
||||
|
||||
/** center top **/
|
||||
.TE333 {
|
||||
top: 128px;
|
||||
left: 660px;
|
||||
}
|
||||
.TE335 {
|
||||
top: 128px;
|
||||
left: 775px;
|
||||
}
|
||||
.TE337 {
|
||||
top: 128px;
|
||||
left: 880px;
|
||||
}
|
||||
.TE339 {
|
||||
top: 128px;
|
||||
left: 1000px;
|
||||
}
|
||||
.TE341 {
|
||||
top: 128px;
|
||||
left: 1110px;
|
||||
}
|
||||
.TE343 {
|
||||
top: 128px;
|
||||
left: 1225px;
|
||||
}
|
||||
.TE345 {
|
||||
top: 128px;
|
||||
left: 1335px;
|
||||
}
|
||||
.TE347 {
|
||||
top: 128px;
|
||||
left: 1440px;
|
||||
}
|
||||
|
||||
/** center bottom **/
|
||||
.TE334 {
|
||||
top: 620px;
|
||||
left: 610px;
|
||||
}
|
||||
.TE336 {
|
||||
top: 620px;
|
||||
left: 730px;
|
||||
}
|
||||
.TE338 {
|
||||
top: 620px;
|
||||
left: 860px;
|
||||
}
|
||||
.TE340 {
|
||||
top: 620px;
|
||||
left: 980px;
|
||||
}
|
||||
.TE342 {
|
||||
top: 620px;
|
||||
left: 1110px;
|
||||
}
|
||||
.TE344 {
|
||||
top: 620px;
|
||||
left: 1235px;
|
||||
}
|
||||
.TE346 {
|
||||
top: 620px;
|
||||
left: 1360px;
|
||||
}
|
||||
.TE348 {
|
||||
top: 620px;
|
||||
left: 1480px;
|
||||
}
|
||||
|
||||
/** center middle **/
|
||||
.TE301 {
|
||||
top: 340px;
|
||||
transform: scaleY(0.8);
|
||||
left: 450px;
|
||||
}
|
||||
.TE302 {
|
||||
top: 400px;
|
||||
transform: scaleY(0.8);
|
||||
left: 450px;
|
||||
}
|
||||
.TE303 {
|
||||
top: 460px;
|
||||
transform: scaleY(0.8);
|
||||
left: 450px;
|
||||
}
|
||||
.TE304 {
|
||||
top: 400px;
|
||||
/* transform: scaleY(0.8) skewX(-2deg); */
|
||||
transform: scaleY(0.8);
|
||||
left: 580px;
|
||||
}
|
||||
.TE305 {
|
||||
top: 340px;
|
||||
/* transform: scaleY(0.8) skewX(-2deg); */
|
||||
transform: scaleY(0.8);
|
||||
left: 720px;
|
||||
}
|
||||
.TE306 {
|
||||
top: 400px;
|
||||
/* transform: scaleY(0.8) skewX(-2deg); */
|
||||
/* transform: scaleY(0.8) rotate(-1deg); */
|
||||
transform: scaleY(0.8);
|
||||
left: 720px;
|
||||
}
|
||||
.TE307 {
|
||||
top: 460px;
|
||||
/* transform: scaleY(0.8) rotate(-1deg); */
|
||||
transform: scaleY(0.8);
|
||||
left: 720px;
|
||||
}
|
||||
.TE308 {
|
||||
top: 400px;
|
||||
transform: scaleY(0.8);
|
||||
left: 860px;
|
||||
}
|
||||
.TE309 {
|
||||
top: 400px;
|
||||
transform: scaleY(0.8);
|
||||
left: 1000px;
|
||||
}
|
||||
.TE310 {
|
||||
top: 400px;
|
||||
transform: scaleY(0.8);
|
||||
left: 1140px;
|
||||
}
|
||||
.TE311 {
|
||||
top: 340px;
|
||||
transform: scaleY(0.8);
|
||||
left: 1280px;
|
||||
}
|
||||
.TE312 {
|
||||
top: 400px;
|
||||
transform: scaleY(0.8);
|
||||
left: 1280px;
|
||||
}
|
||||
.TE313 {
|
||||
top: 460px;
|
||||
transform: scaleY(0.8);
|
||||
left: 1280px;
|
||||
}
|
||||
.TE314 {
|
||||
top: 400px;
|
||||
transform: scaleY(0.8);
|
||||
left: 1420px;
|
||||
}
|
||||
.TE315 {
|
||||
top: 400px;
|
||||
transform: scaleY(0.8);
|
||||
left: 1560px;
|
||||
}
|
||||
.TE316 {
|
||||
top: 400px;
|
||||
transform: scaleY(0.8);
|
||||
left: 1700px;
|
||||
}
|
||||
.TE317 {
|
||||
top: 340px;
|
||||
transform: scaleY(0.8);
|
||||
left: 1840px;
|
||||
}
|
||||
.TE318 {
|
||||
top: 400px;
|
||||
transform: scaleY(0.8);
|
||||
left: 1840px;
|
||||
}
|
||||
.TE319 {
|
||||
top: 460px;
|
||||
transform: scaleY(0.8);
|
||||
left: 1840px;
|
||||
}
|
||||
|
||||
/** right **/
|
||||
.TE327 {
|
||||
top: 152px;
|
||||
left: 2000px;
|
||||
transform: scale(0.8) skewX(5deg);
|
||||
}
|
||||
.TE320 {
|
||||
top: 252px;
|
||||
left: 2020px;
|
||||
transform: scale(0.8) skewX(7deg);
|
||||
}
|
||||
.TE321 {
|
||||
top: 400px;
|
||||
left: 2040px;
|
||||
transform: scale(0.8) skewX(7deg);
|
||||
}
|
||||
.TE322 {
|
||||
top: 532px;
|
||||
left: 2060px;
|
||||
transform: scale(0.8) skewX(7deg);
|
||||
}
|
||||
.TE330 {
|
||||
top: 656px;
|
||||
left: 2080px;
|
||||
transform: scale(0.8) skewX(7deg);
|
||||
}
|
||||
.TE323 {
|
||||
top: 152px;
|
||||
left: 2100px;
|
||||
transform: scale(0.8) skewX(7deg);
|
||||
}
|
||||
.TE328 {
|
||||
top: 252px;
|
||||
left: 2120px;
|
||||
transform: scale(0.8) skewX(7deg);
|
||||
}
|
||||
.TE331 {
|
||||
top: 400px;
|
||||
left: 2140px;
|
||||
transform: scale(0.8) skewX(7deg);
|
||||
}
|
||||
.TE329 {
|
||||
top: 532px;
|
||||
left: 2160px;
|
||||
transform: scale(0.8) skewX(7deg);
|
||||
}
|
||||
.TE326 {
|
||||
top: 656px;
|
||||
left: 2180px;
|
||||
transform: scale(0.8) skewX(7deg);
|
||||
}
|
||||
.TE324 {
|
||||
top: 252px;
|
||||
left: 2220px;
|
||||
transform: scale(0.8) skewX(7deg);
|
||||
}
|
||||
.TE332 {
|
||||
top: 400px;
|
||||
left: 2260px;
|
||||
transform: scale(0.8) skewX(7deg);
|
||||
}
|
||||
.TE325 {
|
||||
top: 532px;
|
||||
left: 2260px;
|
||||
transform: scale(0.8) skewX(7deg);
|
||||
}
|
@ -6,7 +6,6 @@ function BottomBarItem(props) {
|
||||
<Container
|
||||
icon={props.icon}
|
||||
title={props.title}
|
||||
desc={props.desc}
|
||||
className={`${cls.bottomBarItem} ${props.className}`}
|
||||
style={props.style}
|
||||
>
|
||||
|
@ -32,7 +32,7 @@ export default function CompanyName() {
|
||||
<img src={TopSide} alt="图片丢失" className={cls.TopSideLeft}/>
|
||||
<div className={cls.TopSideLeftLine}>
|
||||
<img src={LeftLine} alt="图片丢失" className={cls.TopSideLeftLineicon}/>
|
||||
<h2 className={cls.TopSideLeftTxt}>单位:河南汇融数字科技有限公司</h2>
|
||||
<h2 className={cls.TopSideLeftTxt}>单位:河南汇融科技服务有限公司</h2>
|
||||
</div>
|
||||
<div>
|
||||
<h2 className={cls.TopTitleText}>
|
||||
|
@ -38,10 +38,9 @@
|
||||
.TopSideLeftTxt {
|
||||
margin-right: 120px;
|
||||
margin-top: 15px;
|
||||
color: rgb(255, 255, 255, 0.6);
|
||||
color: rgb(255, 255, 255, 0.8);
|
||||
font-size: 20px;
|
||||
font-weight: 300px;
|
||||
letter-spacing: 1px;
|
||||
line-height: 22.174976px;
|
||||
}
|
||||
}
|
||||
@ -78,9 +77,9 @@
|
||||
}
|
||||
|
||||
.TopTitleText {
|
||||
margin-top: 40px;
|
||||
margin-top: 16px;
|
||||
letter-spacing: 8px;
|
||||
font-size: 34px;
|
||||
font-size: 32px;
|
||||
color: #00fff7;
|
||||
text-align: center;
|
||||
letter-spacing: 2px;
|
||||
|
@ -1,153 +1,73 @@
|
||||
import BottomBarItem from "../BottomItemBackground";
|
||||
import React, { Component } from "react";
|
||||
import cls from "./righttable.module.scss";
|
||||
import { useSelector } from "react-redux";
|
||||
|
||||
import { ScrollBoard } from "@jiaminghi/data-view-react";
|
||||
|
||||
function Chart1(props) {
|
||||
const rawData = useSelector((state) => state.cutting.productData);
|
||||
|
||||
let config = {
|
||||
// headerBGC: "rgba(4, 44, 76, 0.3)",
|
||||
headerBGC: "#044A8460",
|
||||
header: [
|
||||
'<span style="color:#fff; padding-left: 8px;">产线名<span/>',
|
||||
'<span style="color:#fff; padding-left: 8px;">玻璃长度<span/>',
|
||||
'<span style="color:#fff; padding-left: 8px;">玻璃宽度<span/>',
|
||||
'<span style="color:#fff; padding-left: 8px;">玻璃厚度<span/>',
|
||||
],
|
||||
// oddRowBGC: "#042444",
|
||||
// evenRowBGC: "#042c4c",
|
||||
oddRowBGC: "#044A8460",
|
||||
evenRowBGC: "#0b549970",
|
||||
columnWidth: [128],
|
||||
headerHeight: 40,
|
||||
hoverPause: true,
|
||||
data: replaceStyle(filterData(rawData), 0.7),
|
||||
};
|
||||
|
||||
return (
|
||||
<BottomBarItem
|
||||
icon="pause"
|
||||
title="当前产线生产规格"
|
||||
className={props.className}
|
||||
style={props.style}
|
||||
>
|
||||
<div
|
||||
className={cls.CenterChart1itemDetailBorder}
|
||||
style={{ paddingTop: "6px" }}
|
||||
>
|
||||
<span className={cls.CenterFormitemDetailBorderLine1}></span>
|
||||
<span className={cls.CenterFormitemDetailBorderLine2}></span>
|
||||
<span className={cls.CenterFormitemDetailBorderLine3}></span>
|
||||
{config.data.length !== 0 && <ScrollBoard config={config} style={{}} />}
|
||||
{config.data.length === 0 && (
|
||||
<p
|
||||
style={{
|
||||
color: "#cccf",
|
||||
fontSize: "24px",
|
||||
userSelect: "none",
|
||||
textAlign: "center",
|
||||
paddingTop: "72px",
|
||||
}}
|
||||
>
|
||||
暂无数据
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
</BottomBarItem>
|
||||
);
|
||||
}
|
||||
|
||||
export default Chart1;
|
||||
|
||||
// 测试数据
|
||||
var rawData = [
|
||||
{
|
||||
id: 1,
|
||||
length: 1209,
|
||||
productionLine: "Y61",
|
||||
square: 123.3,
|
||||
thick: 2,
|
||||
wide: 1089,
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
length: 1119,
|
||||
productionLine: "Y62",
|
||||
square: 103.3,
|
||||
thick: 2,
|
||||
wide: 1339,
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
length: 1019,
|
||||
productionLine: "Y63",
|
||||
square: 233,
|
||||
thick: 1,
|
||||
wide: 1111,
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
length: 2000,
|
||||
productionLine: "Y64",
|
||||
square: 233,
|
||||
thick: 1,
|
||||
wide: 1232,
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
length: 1560,
|
||||
productionLine: "Y65",
|
||||
square: 233,
|
||||
thick: 1,
|
||||
wide: 996,
|
||||
},
|
||||
{
|
||||
id: 6,
|
||||
length: 1990,
|
||||
productionLine: "Y66",
|
||||
square: 233,
|
||||
thick: 1,
|
||||
wide: 416,
|
||||
},
|
||||
let data = [
|
||||
["产线0", "10mm", "10mm", "10mm"],
|
||||
["产线2", "8mm", "8mm", "8mm"],
|
||||
["产线3", "15mm", "15mm", "15mm"],
|
||||
["产线4", "15mm", "15mm", "15mm"],
|
||||
["产线42", "15mm", "15mm", "15mm"],
|
||||
["产线5", "15mm", "15mm", "15mm"],
|
||||
["产线6", "15mm", "15mm", "15mm"],
|
||||
];
|
||||
|
||||
function filterData(rawData) {
|
||||
return (rawData ?? []).map((item) => [
|
||||
// 产线名
|
||||
item.productionLine,
|
||||
// 原板宽度
|
||||
item.length,
|
||||
// 净板宽
|
||||
item.wide,
|
||||
// 玻璃厚度
|
||||
item.thick,
|
||||
]);
|
||||
}
|
||||
let header = ["产线名", "原板宽度", "净板宽", "玻璃厚度"];
|
||||
|
||||
// let data = [
|
||||
// ["产线0", "10mm", "10mm", "10mm"],
|
||||
// ["产线2", "8mm", "8mm", "8mm"],
|
||||
// ["产线3", "15mm", "15mm", "15mm"],
|
||||
// ["产线4", "15mm", "15mm", "15mm"],
|
||||
// ["产线42", "15mm", "15mm", "15mm"],
|
||||
// ["产线5", "15mm", "15mm", "15mm"],
|
||||
// ["产线6", "15mm", "15mm", "15mm"],
|
||||
// ];
|
||||
let config = {
|
||||
headerBGC: "rgba(4, 44, 76, 0.3)",
|
||||
header: [
|
||||
'<span style="color:#fff">产线名<span/>',
|
||||
'<span style="color:#fff">原板宽度<span/>',
|
||||
'<span style="color:#fff">净板宽<span/>',
|
||||
'<span style="color:#fff">玻璃厚度<span/>',
|
||||
],
|
||||
oddRowBGC: "#042444",
|
||||
evenRowBGC: "#042c4c",
|
||||
columnWidth: [128],
|
||||
headerHeight: 40,
|
||||
hoverPause: false,
|
||||
data: replaceStyle(data, 0.7),
|
||||
};
|
||||
|
||||
// let header = ["产线名", "原板宽度", "净板宽", "玻璃厚度"];
|
||||
|
||||
function replaceStyle(Arr, opacity) {
|
||||
function replaceStyle(Arr, opencity) {
|
||||
let temp = [];
|
||||
|
||||
for (let i = 0; i < Arr.length; i++) {
|
||||
temp[i] = [];
|
||||
for (let j = 0; j < Arr[i].length; j++) {
|
||||
temp[i][j] = `<span style="color:rgba(255, 255, 255,${opacity})">${
|
||||
Arr[i][j]
|
||||
} ${j == 0 ? "" : "mm"}<span/>`;
|
||||
temp[i][
|
||||
j
|
||||
] = ` <span style="color:rgba(255, 255, 255,${opencity})">${Arr[i][j]}<span/>`;
|
||||
}
|
||||
}
|
||||
|
||||
return temp;
|
||||
}
|
||||
|
||||
class Chart1 extends Component {
|
||||
render() {
|
||||
return (
|
||||
<BottomBarItem
|
||||
icon="pause"
|
||||
title="当前产线生产规格"
|
||||
className={this.props.className}
|
||||
style={this.props.style}
|
||||
>
|
||||
<div
|
||||
className={cls.CenterChart1itemDetailBorder}
|
||||
style={{ paddingTop: "6px" }}
|
||||
>
|
||||
<span className={cls.CenterFormitemDetailBorderLine1}></span>
|
||||
<span className={cls.CenterFormitemDetailBorderLine2}></span>
|
||||
<span className={cls.CenterFormitemDetailBorderLine3}></span>
|
||||
<ScrollBoard config={config} style={{}} />
|
||||
</div>
|
||||
</BottomBarItem>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default Chart1;
|
||||
|
@ -5,7 +5,7 @@
|
||||
flex-direction: column;
|
||||
justify-content: flex-start;
|
||||
|
||||
// background-color: rgba(4, 44, 76, 0.2);
|
||||
background-color: rgba(4, 44, 76, 0.2);
|
||||
.CenterChart1itemTXT {
|
||||
width: 100%;
|
||||
height: 10%;
|
||||
|
Binary file not shown.
@ -1,7 +0,0 @@
|
||||
@font-face {
|
||||
font-family: "HelloFont WenYiHei";
|
||||
/* font-style: normal;
|
||||
font-weight: 400; */
|
||||
src: url("./ziyou.ttf");
|
||||
/* font-display: swap; */
|
||||
}
|
@ -1,259 +1,138 @@
|
||||
import GraphBase from "../GraphBase";
|
||||
import "./font.css";
|
||||
import cls from "./index.module.css";
|
||||
import { useEffect, useState } from "react";
|
||||
import { Tooltip, Button } from "antd";
|
||||
import { InfoCircleOutlined } from "@ant-design/icons";
|
||||
import { useSelector } from "react-redux";
|
||||
import BottomBarItem from '../BottomItemBackground';
|
||||
import GraphBase from '../GraphBase';
|
||||
import { Radio } from 'antd';
|
||||
import cls from './index.module.css';
|
||||
import { useState } from 'react';
|
||||
|
||||
const SmallBox = (props) => {
|
||||
return (
|
||||
<div
|
||||
className="small-box"
|
||||
style={{
|
||||
boxShadow: "inset 0 0 18px 10px #fff1",
|
||||
borderRadius: "3px",
|
||||
padding: "6px",
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
color: "#fff",
|
||||
position: "relative",
|
||||
userSelect: "none",
|
||||
}}
|
||||
>
|
||||
{props.split !== false && (
|
||||
<span
|
||||
className="vertical-line"
|
||||
style={{
|
||||
position: "absolute",
|
||||
display: "inline-block",
|
||||
width: "2px",
|
||||
height: "80%",
|
||||
top: "10%",
|
||||
left: "45%",
|
||||
background:
|
||||
"linear-gradient(to bottom, transparent, #fff3, #fffa, #fff3, transparent)",
|
||||
}}
|
||||
></span>
|
||||
)}
|
||||
{props.children}
|
||||
</div>
|
||||
);
|
||||
return (
|
||||
<div
|
||||
className="small-box"
|
||||
style={{
|
||||
boxShadow: 'inset 0 0 18px 10px #fff1',
|
||||
borderRadius: '3px',
|
||||
padding: '6px',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
color: '#fff',
|
||||
position: 'relative',
|
||||
userSelect: 'none',
|
||||
}}
|
||||
>
|
||||
{props.split !== false && (
|
||||
<span
|
||||
className="vertical-line"
|
||||
style={{
|
||||
position: 'absolute',
|
||||
display: 'inline-block',
|
||||
width: '2px',
|
||||
height: '80%',
|
||||
top: '10%',
|
||||
left: '50%',
|
||||
background:
|
||||
'linear-gradient(to bottom, transparent, #fff3, #fffa, #fff3, transparent)',
|
||||
}}
|
||||
></span>
|
||||
)}
|
||||
{props.children}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
function WindFrequence(props) {
|
||||
const [dataSource, setDataSource] = useState("Y61");
|
||||
const [currentLineTemp, setCurrentLineTemp] = useState([]);
|
||||
const currentTempList = useSelector((state) => state.annealTemperature?.data);
|
||||
const lines = ["Y61", "Y62", "Y63", "Y64", "Y65"];
|
||||
function handleSourceChange(line) {
|
||||
setDataSource(line);
|
||||
}
|
||||
const [dataSource, setDataSource] = useState('风机');
|
||||
|
||||
useEffect(() => {
|
||||
setCurrentLineTemp(
|
||||
(currentTempList &&
|
||||
currentTempList[1 + lines.indexOf(dataSource) + "#"]) ||
|
||||
[]
|
||||
);
|
||||
}, [dataSource]);
|
||||
function handleSourceChange(v) {
|
||||
console.log('val', v);
|
||||
}
|
||||
|
||||
return (
|
||||
<GraphBase
|
||||
icon="temp"
|
||||
title="当前温度"
|
||||
dateOptions={["Y61", "Y62", "Y63", "Y64", "Y65"]}
|
||||
selectWidth={70}
|
||||
defaultSelect={dataSource}
|
||||
onDateChange={handleSourceChange}
|
||||
size={["middle", "long"]}
|
||||
>
|
||||
<div className={cls.mainContent + " " + cls.grid}>
|
||||
<SmallBox>
|
||||
<h1 className={cls.areaName}>A1区板上</h1>
|
||||
<div className={cls.areaContent}>
|
||||
<span className={cls.areaValue}>
|
||||
{(+currentLineTemp[0]).toFixed(2) || 0} ℃
|
||||
</span>
|
||||
<span className={cls.areaValue}>
|
||||
{(+currentLineTemp[1]).toFixed(2) || 0} ℃
|
||||
</span>
|
||||
<span className={cls.areaValue}>
|
||||
{(+currentLineTemp[2]).toFixed(2) || 0} ℃
|
||||
</span>
|
||||
</div>
|
||||
</SmallBox>
|
||||
<SmallBox>
|
||||
<h1 className={cls.areaName}>A2区板上</h1>
|
||||
<div className={cls.areaContent}>
|
||||
<span className={cls.areaValue}>
|
||||
{(+currentLineTemp[6]).toFixed(2) || 0} ℃
|
||||
</span>
|
||||
<span className={cls.areaValue}>
|
||||
{(+currentLineTemp[7]).toFixed(2) || 0} ℃
|
||||
</span>
|
||||
<span className={cls.areaValue}>
|
||||
{(+currentLineTemp[8]).toFixed(2) || 0} ℃
|
||||
</span>
|
||||
</div>
|
||||
</SmallBox>
|
||||
<SmallBox>
|
||||
<h1 className={cls.areaName}>B区板上</h1>
|
||||
<div className={cls.areaContent}>
|
||||
<span className={cls.areaValue}>
|
||||
{(+currentLineTemp[12]).toFixed(2) || 0} ℃
|
||||
</span>
|
||||
<span className={cls.areaValue}>
|
||||
{(+currentLineTemp[13]).toFixed(2) || 0} ℃
|
||||
</span>
|
||||
<span className={cls.areaValue}>
|
||||
{(+currentLineTemp[14]).toFixed(2) || 0} ℃
|
||||
</span>
|
||||
</div>
|
||||
</SmallBox>
|
||||
<SmallBox>
|
||||
<h1 className={cls.areaName}>C区板上</h1>
|
||||
<div className={cls.areaContent}>
|
||||
<span className={cls.areaValue}>
|
||||
{(+currentLineTemp[18]).toFixed(2) || 0} ℃
|
||||
</span>
|
||||
<span className={cls.areaValue}>
|
||||
{(+currentLineTemp[19]).toFixed(2) || 0} ℃
|
||||
</span>
|
||||
<span className={cls.areaValue}>
|
||||
{(+currentLineTemp[20]).toFixed(2) || 0} ℃
|
||||
</span>
|
||||
</div>
|
||||
</SmallBox>
|
||||
<SmallBox>
|
||||
<h1 className={cls.areaName}>A1区板下</h1>
|
||||
<div className={cls.areaContent}>
|
||||
<span className={cls.areaValue}>
|
||||
{(+currentLineTemp[3]).toFixed(2) || 0} ℃
|
||||
</span>
|
||||
<span className={cls.areaValue}>
|
||||
{(+currentLineTemp[4]).toFixed(2) || 0} ℃
|
||||
</span>
|
||||
<span className={cls.areaValue}>
|
||||
{(+currentLineTemp[5]).toFixed(2) || 0} ℃
|
||||
</span>
|
||||
</div>
|
||||
</SmallBox>
|
||||
<SmallBox>
|
||||
<h1 className={cls.areaName}>A2区板下</h1>
|
||||
<div className={cls.areaContent}>
|
||||
<span className={cls.areaValue}>
|
||||
{(+currentLineTemp[9]).toFixed(2) || 0} ℃
|
||||
</span>
|
||||
<span className={cls.areaValue}>
|
||||
{(+currentLineTemp[10]).toFixed(2) || 0} ℃
|
||||
</span>
|
||||
<span className={cls.areaValue}>
|
||||
{(+currentLineTemp[11]).toFixed(2) || 0} ℃
|
||||
</span>
|
||||
</div>
|
||||
</SmallBox>
|
||||
<SmallBox>
|
||||
<h1 className={cls.areaName}>B区板下</h1>
|
||||
<div className={cls.areaContent}>
|
||||
<span className={cls.areaValue}>
|
||||
{(+currentLineTemp[15]).toFixed(2) || 0} ℃
|
||||
</span>
|
||||
<span className={cls.areaValue}>
|
||||
{(+currentLineTemp[16]).toFixed(2) || 0} ℃
|
||||
</span>
|
||||
<span className={cls.areaValue}>
|
||||
{(+currentLineTemp[17]).toFixed(2) || 0} ℃
|
||||
</span>
|
||||
</div>
|
||||
</SmallBox>
|
||||
<SmallBox>
|
||||
<h1 className={cls.areaName}>C区板下</h1>
|
||||
<div className={cls.areaContent}>
|
||||
<span className={cls.areaValue}>
|
||||
{(+currentLineTemp[21]).toFixed(2) || 0} ℃
|
||||
</span>
|
||||
<span className={cls.areaValue}>
|
||||
{(+currentLineTemp[22]).toFixed(2) || 0} ℃
|
||||
</span>
|
||||
<span className={cls.areaValue}>
|
||||
{(+currentLineTemp[23]).toFixed(2) || 0} ℃
|
||||
</span>
|
||||
</div>
|
||||
</SmallBox>
|
||||
<SmallBox split={false} style={{ position: "relative" }}>
|
||||
<div className={cls.areaPureContent}>
|
||||
<div
|
||||
className="hint"
|
||||
style={{ position: "absolute", top: "3px", right: "3px" }}
|
||||
>
|
||||
<Tooltip title="红外温度">
|
||||
<Button
|
||||
shape="circle"
|
||||
type="text"
|
||||
style={{ color: "#cccc" }}
|
||||
icon={<InfoCircleOutlined />}
|
||||
></Button>
|
||||
</Tooltip>
|
||||
</div>
|
||||
<span className={cls.areaPureValue} style={{ fontSize: "12px" }}>
|
||||
{(+currentLineTemp[26]).toFixed(2) || 0}℃
|
||||
</span>
|
||||
<span className={cls.areaPureValue} style={{ fontSize: "12px" }}>
|
||||
{(+currentLineTemp[27]).toFixed(2) || 0}℃
|
||||
</span>
|
||||
<span className={cls.areaPureValue} style={{ fontSize: "12px" }}>
|
||||
{(+currentLineTemp[28]).toFixed(2) || 0}℃
|
||||
</span>
|
||||
</div>
|
||||
</SmallBox>
|
||||
|
||||
<SmallBox split={false} style={{ position: "relative" }}>
|
||||
<div className={cls.areaPureContent}>
|
||||
<div
|
||||
className="hint"
|
||||
style={{ position: "absolute", top: "3px", right: "3px" }}
|
||||
>
|
||||
<Tooltip title="压延机冷却水温度 | 过度辊台冷却水温度 | 唇砖冷却水温度">
|
||||
<Button
|
||||
shape="circle"
|
||||
type="text"
|
||||
style={{ color: "#cccc" }}
|
||||
icon={<InfoCircleOutlined />}
|
||||
></Button>
|
||||
</Tooltip>
|
||||
</div>
|
||||
<span className={cls.areaPureValue} style={{ fontSize: "12px" }}>
|
||||
{(+currentLineTemp[29]).toFixed(2) || 0}℃
|
||||
</span>
|
||||
<span className={cls.areaPureValue} style={{ fontSize: "12px" }}>
|
||||
{(+currentLineTemp[30]).toFixed(2) || 0}℃
|
||||
</span>
|
||||
<span className={cls.areaPureValue} style={{ fontSize: "12px" }}>
|
||||
{(+currentLineTemp[31]).toFixed(2) || 0}℃
|
||||
</span>
|
||||
</div>
|
||||
</SmallBox>
|
||||
<SmallBox>
|
||||
<h1 className={cls.areaName}>RET1区</h1>
|
||||
<div className={cls.areaContent}>
|
||||
<span className={cls.areaValue}>
|
||||
{(+currentLineTemp[24]).toFixed(2) || 0} ℃
|
||||
</span>
|
||||
</div>
|
||||
</SmallBox>
|
||||
<SmallBox>
|
||||
<h1 className={cls.areaName}>RET2区</h1>
|
||||
<div className={cls.areaContent}>
|
||||
<span className={cls.areaValue}>
|
||||
{(+currentLineTemp[25]).toFixed(2) || 0} ℃
|
||||
</span>
|
||||
</div>
|
||||
</SmallBox>
|
||||
</div>
|
||||
</GraphBase>
|
||||
);
|
||||
return (
|
||||
<GraphBase
|
||||
icon="pause"
|
||||
title="当前温度"
|
||||
dateOptions={['风机', '风阀', '电加热']}
|
||||
onDateChange={handleSourceChange}
|
||||
size={['middle', 'long']}
|
||||
>
|
||||
<div className={cls.mainContent + ' ' + cls.grid}>
|
||||
<SmallBox>
|
||||
<h1 className={cls.areaName}>A1区板上</h1>
|
||||
<div className={cls.areaContent}>
|
||||
<span className={cls.areaValue}>123.8℃</span>
|
||||
<span className={cls.areaValue}>123.8℃</span>
|
||||
<span className={cls.areaValue}>123.8℃</span>
|
||||
</div>
|
||||
</SmallBox>
|
||||
<SmallBox>
|
||||
<h1 className={cls.areaName}>A1区板上</h1>
|
||||
<div className={cls.areaContent}>
|
||||
<span className={cls.areaValue}>123.8℃</span>
|
||||
<span className={cls.areaValue}>123.8℃</span>
|
||||
<span className={cls.areaValue}>123.8℃</span>
|
||||
</div>
|
||||
</SmallBox>
|
||||
<SmallBox>
|
||||
<h1 className={cls.areaName}>A1区板上</h1>
|
||||
<div className={cls.areaContent}>
|
||||
<span className={cls.areaValue}>123.8℃</span>
|
||||
<span className={cls.areaValue}>123.8℃</span>
|
||||
<span className={cls.areaValue}>123.8℃</span>
|
||||
</div>
|
||||
</SmallBox>
|
||||
<SmallBox>
|
||||
<h1 className={cls.areaName}>A1区板上</h1>
|
||||
<div className={cls.areaContent}>
|
||||
<span className={cls.areaValue}>123.8℃</span>
|
||||
<span className={cls.areaValue}>123.8℃</span>
|
||||
<span className={cls.areaValue}>123.8℃</span>
|
||||
</div>
|
||||
</SmallBox>
|
||||
<SmallBox>
|
||||
<h1 className={cls.areaName}>A1区板上</h1>
|
||||
<div className={cls.areaContent}>
|
||||
<span className={cls.areaValue}>123.8℃</span>
|
||||
<span className={cls.areaValue}>123.8℃</span>
|
||||
<span className={cls.areaValue}>123.8℃</span>
|
||||
</div>
|
||||
</SmallBox>
|
||||
<SmallBox split={false}>
|
||||
<div className={cls.areaPureContent}>
|
||||
<span className={cls.areaPureValue}>123.8℃</span>
|
||||
<span className={cls.areaPureValue}>123.8℃</span>
|
||||
<span className={cls.areaPureValue}>123.8℃</span>
|
||||
</div>
|
||||
</SmallBox>
|
||||
<SmallBox>
|
||||
<h1 className={cls.areaName}>A1区板上</h1>
|
||||
<div className={cls.areaContent}>
|
||||
<span className={cls.areaValue}>123.8℃</span>
|
||||
<span className={cls.areaValue}>123.8℃</span>
|
||||
<span className={cls.areaValue}>123.8℃</span>
|
||||
</div>
|
||||
</SmallBox>
|
||||
<SmallBox split={false}>
|
||||
<div className={cls.areaPureContent}>
|
||||
<span className={cls.areaPureValue}>123.8℃</span>
|
||||
<span className={cls.areaPureValue}>123.8℃</span>
|
||||
<span className={cls.areaPureValue}>123.8℃</span>
|
||||
</div>
|
||||
</SmallBox>
|
||||
<SmallBox>
|
||||
<h1 className={cls.areaName}>A1区板上</h1>
|
||||
<div className={cls.areaContent}>
|
||||
<span className={cls.areaValue}>123.8℃</span>
|
||||
</div>
|
||||
</SmallBox>
|
||||
<SmallBox>
|
||||
<h1 className={cls.areaName}>A1区板上</h1>
|
||||
<div className={cls.areaContent}>
|
||||
<span className={cls.areaValue}>123.8℃</span>
|
||||
</div>
|
||||
</SmallBox>
|
||||
</div>
|
||||
</GraphBase>
|
||||
);
|
||||
}
|
||||
|
||||
export default WindFrequence;
|
||||
|
@ -1,141 +1,139 @@
|
||||
.chart {
|
||||
height: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.gas {
|
||||
position: relative;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.currentFlow {
|
||||
position: absolute;
|
||||
top: 20px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
padding: 8px 22px;
|
||||
border-radius: 2px;
|
||||
letter-spacing: 2px;
|
||||
box-shadow: inset 0 0 22px 0px hsla(0, 0%, 100%, 0.15);
|
||||
line-height: 18px;
|
||||
font-size: 18px;
|
||||
text-align: center;
|
||||
color: #12fff5;
|
||||
position: absolute;
|
||||
top: 20px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
padding: 8px 22px;
|
||||
border-radius: 2px;
|
||||
letter-spacing: 2px;
|
||||
box-shadow: inset 0 0 22px 0px hsla(0, 0%, 100%, 0.15);
|
||||
line-height: 18px;
|
||||
font-size: 18px;
|
||||
text-align: center;
|
||||
color: #12fff5;
|
||||
}
|
||||
|
||||
.floatHead {
|
||||
position: absolute;
|
||||
top: 22px;
|
||||
right: 24px;
|
||||
height: 32px;
|
||||
width: 410px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
position: absolute;
|
||||
top: 22px;
|
||||
right: 24px;
|
||||
height: 32px;
|
||||
width: 410px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.mainContent {
|
||||
padding-top: 16px;
|
||||
padding-top: 16px;
|
||||
}
|
||||
|
||||
.alignRight {
|
||||
text-align: right;
|
||||
justify-self: flex-end;
|
||||
text-align: right;
|
||||
justify-self: flex-end;
|
||||
}
|
||||
|
||||
.grid {
|
||||
display: grid;
|
||||
gap: 6px;
|
||||
grid-template-columns: repeat(2, minmax(100px, 1fr));
|
||||
grid-auto-rows: minmax(64px, min-content);
|
||||
display: grid;
|
||||
gap: 6px;
|
||||
grid-template-columns: repeat(2, minmax(100px, 1fr));
|
||||
grid-auto-rows: minmax(64px, min-content);
|
||||
}
|
||||
|
||||
.areaName {
|
||||
color: #fff;
|
||||
font-size: 18px;
|
||||
line-height: 1;
|
||||
letter-spacing: 1.5px;
|
||||
margin: 0;
|
||||
padding-left: 20px;
|
||||
width: 50%;
|
||||
color: #fff;
|
||||
font-size: 20px;
|
||||
line-height: 1;
|
||||
letter-spacing: 1.5px;
|
||||
margin: 0;
|
||||
padding-left: 20px;
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
.areaPureContent {
|
||||
display: flex;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.areaPureValue {
|
||||
padding: 0 8px;
|
||||
padding: 0 8px;
|
||||
}
|
||||
|
||||
span.areaPureValue:not(:first-of-type) {
|
||||
border-left: 2px solid #fff6;
|
||||
.areaPureValue:not(:first-child) {
|
||||
border-left: 2px solid #fff6;
|
||||
}
|
||||
|
||||
.areaContent {
|
||||
width: 50%;
|
||||
padding-left: 12px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 50%;
|
||||
padding-left: 12px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.areaPureValue,
|
||||
.areaValue {
|
||||
display: inline-block;
|
||||
font-size: 14px;
|
||||
line-height: 16px;
|
||||
letter-spacing: 1.2px;
|
||||
font-family: "HelloFont WenYiHei", sans-serif;
|
||||
color: #53c2d4;
|
||||
display: inline-block;
|
||||
font-size: 17px;
|
||||
line-height: 22px;
|
||||
letter-spacing: 1.2px;
|
||||
}
|
||||
|
||||
.switchLabel {
|
||||
color: white;
|
||||
margin-left: 6px;
|
||||
color: white;
|
||||
margin-left: 6px;
|
||||
}
|
||||
|
||||
.legend:last-child {
|
||||
margin-left: 8px;
|
||||
margin-left: 8px;
|
||||
}
|
||||
|
||||
.legend > span {
|
||||
display: inline-block;
|
||||
color: #dff1fe;
|
||||
font-size: 14px;
|
||||
letter-spacing: 2px;
|
||||
display: inline-block;
|
||||
color: #dff1fe;
|
||||
font-size: 14px;
|
||||
letter-spacing: 2px;
|
||||
}
|
||||
|
||||
.legend > span:first-child {
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
margin-right: 4px;
|
||||
border-radius: 2px;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
margin-right: 4px;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.gasIcon {
|
||||
background: #12fff5;
|
||||
background: #12fff5;
|
||||
}
|
||||
|
||||
.gas2Icon {
|
||||
background: #2760ff;
|
||||
background: #2760ff;
|
||||
}
|
||||
|
||||
.radioGroup {
|
||||
user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.radioGroup * {
|
||||
border: none !important;
|
||||
border-radius: 0 !important;
|
||||
border: none !important;
|
||||
border-radius: 0 !important;
|
||||
}
|
||||
|
||||
.radioGroup *:focus-within {
|
||||
box-shadow: none !important;
|
||||
box-shadow: none !important;
|
||||
}
|
||||
|
||||
.radioGroup *::before {
|
||||
width: 0 !important;
|
||||
width: 0 !important;
|
||||
}
|
||||
|
||||
.radioGroup_button_wrapper {
|
||||
color: #fff !important;
|
||||
background: #03233c !important;
|
||||
color: #fff !important;
|
||||
background: #03233c !important;
|
||||
}
|
||||
|
Binary file not shown.
@ -1,184 +0,0 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import cls from "./index.module.scss";
|
||||
import { useSelector } from "react-redux";
|
||||
import Arrow from "../../Arrow";
|
||||
|
||||
const EnergyCostRealtime = () => {
|
||||
const [isPage1, setIsPage1] = useState(false);
|
||||
const energyInfo = useSelector((state) => state.energy?.info);
|
||||
|
||||
// function handleClick() {
|
||||
// setIsPage1((pre) => !pre);
|
||||
// }
|
||||
|
||||
useEffect(() => {
|
||||
const timer = setInterval(() => {
|
||||
setIsPage1(pre => !pre);
|
||||
}, 10000);
|
||||
|
||||
return () => {
|
||||
clearInterval(timer);
|
||||
}
|
||||
}, []);
|
||||
return (
|
||||
<>
|
||||
{/* <Arrow key="left" direction="left" onClick={handleClick} />
|
||||
<Arrow key="right" direction="right" onClick={handleClick} /> */}
|
||||
{isPage1 && (
|
||||
<div className={`${cls.cost__info} flex`}>
|
||||
<div className={`${cls.info__item_groups_col1}`}>
|
||||
<div className={cls.info__item}>
|
||||
<i
|
||||
style={{
|
||||
fontSize: "18px",
|
||||
fontStyle: "normal",
|
||||
paddingRight: "6px",
|
||||
}}
|
||||
>
|
||||
余热发电(实时)
|
||||
</i>
|
||||
<span style={{ fontSize: "17px", color: "#3ce8ff" }}>
|
||||
{(+energyInfo?.elecQty2)?.toFixed(2) || 0}kWh
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div className={cls.info__item}>
|
||||
<i
|
||||
style={{
|
||||
fontSize: "18px",
|
||||
fontStyle: "normal",
|
||||
paddingRight: "6px",
|
||||
}}
|
||||
>
|
||||
余热发电(总量)
|
||||
</i>
|
||||
<span style={{ fontSize: "17px", color: "#3ce8ff" }}>
|
||||
{(+energyInfo?.elecQty3)?.toFixed(2) || 0}kWh
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className={cls.info__item_groups}>
|
||||
<div className={cls.info__item}>
|
||||
<i
|
||||
style={{
|
||||
fontSize: "18px",
|
||||
fontStyle: "normal",
|
||||
paddingRight: "6px",
|
||||
}}
|
||||
>
|
||||
水耗量
|
||||
</i>
|
||||
<span style={{ fontSize: "17px", color: "#3ce8ff" }}>
|
||||
{(+energyInfo?.waterQty)?.toFixed(2) || 0}Km³
|
||||
</span>
|
||||
</div>
|
||||
<div className={cls.info__item}>
|
||||
<i
|
||||
style={{
|
||||
fontSize: "18px",
|
||||
fontStyle: "normal",
|
||||
paddingRight: "6px",
|
||||
}}
|
||||
>
|
||||
天然气I
|
||||
</i>
|
||||
<span style={{ fontSize: "17px", color: "#3ce8ff" }}>
|
||||
{energyInfo?.ngQty1 || "0Nm³"}
|
||||
</span>
|
||||
</div>
|
||||
<div className={cls.info__item}>
|
||||
<i
|
||||
style={{
|
||||
fontSize: "18px",
|
||||
fontStyle: "normal",
|
||||
paddingRight: "6px",
|
||||
}}
|
||||
>
|
||||
电耗量
|
||||
</i>
|
||||
<span style={{ fontSize: "17px", color: "#3ce8ff" }}>
|
||||
{(+energyInfo?.elecQty2)?.toFixed(2) || 0}kWh
|
||||
</span>
|
||||
</div>
|
||||
<div className={cls.info__item}>
|
||||
<i
|
||||
style={{
|
||||
fontSize: "18px",
|
||||
fontStyle: "normal",
|
||||
paddingRight: "6px",
|
||||
}}
|
||||
>
|
||||
天然气II
|
||||
</i>
|
||||
<span style={{ fontSize: "17px", color: "#3ce8ff" }}>
|
||||
{energyInfo?.ngQty2 || "0Nm³"}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{!isPage1 && (
|
||||
<div className={cls.energy_info_new}>
|
||||
<div className="energy_info_new--item">
|
||||
<i
|
||||
style={{
|
||||
fontSize: "18px",
|
||||
fontStyle: "normal",
|
||||
paddingRight: "6px",
|
||||
}}
|
||||
>
|
||||
智慧能源光伏发电(昨日)/kwh
|
||||
</i>
|
||||
<span style={{ fontSize: "17px", color: "#3ce8ff" }}>
|
||||
{(+energyInfo?.elecQty6)?.toFixed(2) || 0}kWh
|
||||
</span>
|
||||
</div>
|
||||
<div className="energy_info_new--item">
|
||||
<i
|
||||
style={{
|
||||
fontSize: "18px",
|
||||
fontStyle: "normal",
|
||||
paddingRight: "6px",
|
||||
}}
|
||||
>
|
||||
许昌安彩光伏发电(昨日)/kwh
|
||||
</i>
|
||||
<span style={{ fontSize: "17px", color: "#3ce8ff" }}>
|
||||
{(+energyInfo?.elecQty7)?.toFixed(2) || 0}kWh
|
||||
</span>
|
||||
</div>
|
||||
<div className="energy_info_new--item">
|
||||
<i
|
||||
style={{
|
||||
fontSize: "18px",
|
||||
fontStyle: "normal",
|
||||
paddingRight: "6px",
|
||||
}}
|
||||
>
|
||||
智慧能源光伏发电(总量)/kwh
|
||||
</i>
|
||||
<span style={{ fontSize: "17px", color: "#3ce8ff" }}>
|
||||
{(+energyInfo?.elecQty4)?.toFixed(2) || 0}kWh
|
||||
</span>
|
||||
</div>
|
||||
<div className="energy_info_new--item">
|
||||
<i
|
||||
style={{
|
||||
fontSize: "18px",
|
||||
fontStyle: "normal",
|
||||
paddingRight: "6px",
|
||||
}}
|
||||
>
|
||||
许昌安彩光伏发电(总量)/kwh
|
||||
</i>
|
||||
<span style={{ fontSize: "17px", color: "#3ce8ff" }}>
|
||||
{(+energyInfo?.elecQty5)?.toFixed(2) || 0}kWh
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default EnergyCostRealtime;
|
@ -1,60 +0,0 @@
|
||||
.cost__info {
|
||||
margin-top: 4px;
|
||||
margin-bottom: 6px;
|
||||
// margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.info__item {
|
||||
border-radius: 2px;
|
||||
color: hsl(0, 0%, 100%, 0.9);
|
||||
box-shadow: inset 0 0 17px 0px hsla(0, 0%, 100%, 0.15);
|
||||
font-size: 14px;
|
||||
line-height: 28px;
|
||||
padding-left: 12px;
|
||||
padding: 8px 0;
|
||||
user-select: none;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.hAuto {
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.info__item_groups {
|
||||
flex: 2;
|
||||
margin-left: 8px;
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.info__item_groups_col1 {
|
||||
flex: 1;
|
||||
display: grid;
|
||||
grid-template-rows: 1fr 1fr;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.energy_info_new {
|
||||
color: #fff;
|
||||
display: grid;
|
||||
gap: 8px;
|
||||
grid-template-rows: 1fr 1fr;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
height: 162px;
|
||||
padding: 4px 0;
|
||||
}
|
||||
|
||||
.energy_info_new > div {
|
||||
border-radius: 2px;
|
||||
box-shadow: inset 0 0 17px 0px hsla(0, 0%, 100%, 0.15);
|
||||
font-size: 14px;
|
||||
line-height: 28px;
|
||||
color: hsl(0, 0%, 100%, 0.9);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
@ -1,151 +1,128 @@
|
||||
import cls from "./index.module.css";
|
||||
import { Radio, Select } from "antd";
|
||||
import ReactECharts from "echarts-for-react";
|
||||
import { useState } from "react";
|
||||
import { useSelector } from "react-redux";
|
||||
import { getOptions } from "../../../../utils/energeChartOption";
|
||||
import triangle from "../../../../assets/Icon/triangle.svg";
|
||||
import dayjs from "dayjs";
|
||||
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';
|
||||
|
||||
const EnergyCostChart = (props) => {
|
||||
const elecTrend = useSelector((state) => state.energy.trend.elec);
|
||||
const gasITrend = useSelector((state) => state.energy.trend.natGas1);
|
||||
const gasIITrend = useSelector((state) => state.energy.trend.natGas2);
|
||||
const [source, setSource] = useState("elec");
|
||||
const [period, setPeriod] = useState("week");
|
||||
const options = {
|
||||
color: ['#FFD160', '#12FFF5', '#2760FF'],
|
||||
grid: { top: 32, 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³',
|
||||
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,
|
||||
},
|
||||
],
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
},
|
||||
};
|
||||
|
||||
const [timestr, setTimestr] = useState(
|
||||
dayjs().subtract(7, "day").format("YYYY.MM.DD") +
|
||||
" - " +
|
||||
dayjs().subtract(1, "day").format("YYYY.MM.DD")
|
||||
);
|
||||
function handleSwitchChange(val) {
|
||||
// val: boolean
|
||||
console.log('switch change', val);
|
||||
}
|
||||
|
||||
const currentTrend =
|
||||
source == "elec" ? elecTrend : source == "gasi" ? gasITrend : gasIITrend;
|
||||
|
||||
const options = getOptions(
|
||||
period,
|
||||
source,
|
||||
currentTrend ?? { week: [], month: [], year: [] }
|
||||
);
|
||||
|
||||
function handleDateChange(value) {
|
||||
setPeriod(
|
||||
{
|
||||
周: "week",
|
||||
月: "month",
|
||||
年: "year",
|
||||
}[value]
|
||||
);
|
||||
setTimestr(
|
||||
{
|
||||
年:
|
||||
dayjs().subtract(1, "year").endOf("year").format("YYYY.MM.") +
|
||||
"29 - " +
|
||||
dayjs().endOf("year").format("YYYY.MM.") +
|
||||
"28",
|
||||
周:
|
||||
dayjs().subtract(7, "day").format("YYYY.MM.DD") +
|
||||
" - " +
|
||||
dayjs().subtract(1, "day").format("YYYY.MM.DD"),
|
||||
月:
|
||||
dayjs().subtract(1, "month").format("YYYY.MM.") +
|
||||
"29 - " +
|
||||
dayjs().format("YYYY.MM.") +
|
||||
"28",
|
||||
}[value]
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={cls.energyCostChart}>
|
||||
<div className={cls.titleBar}>
|
||||
<h2>能耗趋势图</h2>
|
||||
</div>
|
||||
|
||||
<div className={`${cls.choiceBar} flex items-center justify-between`}>
|
||||
<Radio.Group
|
||||
value={source}
|
||||
buttonStyle="solid"
|
||||
onChange={(v) => setSource(v.target.value)}
|
||||
className={`${cls.radioGroup} flex items-center justify-between`}
|
||||
>
|
||||
<Radio.Button value="elec" className="radio-group__item">
|
||||
电
|
||||
</Radio.Button>
|
||||
<Radio.Button value="gasi" className="radio-group__item">
|
||||
天然气I
|
||||
</Radio.Button>
|
||||
<Radio.Button value="gasii" className="radio-group__item">
|
||||
天然气II
|
||||
</Radio.Button>
|
||||
</Radio.Group>
|
||||
|
||||
{/* <Radio.Group
|
||||
value={period}
|
||||
buttonStyle="solid"
|
||||
onChange={(v) => setPeriod(v.target.value)}
|
||||
className={cls.radioGroup}
|
||||
>
|
||||
<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 className={cls.graphBaseDesc}>{timestr}</div>
|
||||
|
||||
<Select
|
||||
defaultValue={"周"}
|
||||
style={{ width: 60 }}
|
||||
popupClassName="xc-date-selector-menu"
|
||||
className={cls.radioGroupShort}
|
||||
options={["周", "月", "年"].map((item) => ({
|
||||
label: item,
|
||||
value: item,
|
||||
}))}
|
||||
suffixIcon={<img src={triangle} alt="#" />}
|
||||
notFoundContent={
|
||||
<span
|
||||
style={{
|
||||
color: "#fff",
|
||||
fontSize: "14px",
|
||||
lineHeight: 1,
|
||||
paddingLeft: "12px",
|
||||
}}
|
||||
>
|
||||
- 无 -
|
||||
</span>
|
||||
}
|
||||
onChange={(value, option) => handleDateChange(value)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="flex-1" style={{ marginTop: "8px" }}>
|
||||
{options && (
|
||||
<ReactECharts option={options} style={{ height: "180px" }} />
|
||||
)}
|
||||
{!options && (
|
||||
<p
|
||||
style={{
|
||||
color: "#cccf",
|
||||
fontSize: "20px",
|
||||
userSelect: "none",
|
||||
textAlign: "center",
|
||||
paddingTop: "32px",
|
||||
}}
|
||||
>
|
||||
暂无数据
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
</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>
|
||||
</ul>
|
||||
</div>
|
||||
<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="flex-1">
|
||||
<ReactECharts option={options} style={{ height: '180px' }} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default EnergyCostChart;
|
||||
|
@ -1,95 +1,85 @@
|
||||
.energyCostChart {
|
||||
height: 1px;
|
||||
flex: 1;
|
||||
padding-top: 8px;
|
||||
height: 1px;
|
||||
flex: 1;
|
||||
padding-top: 8px;
|
||||
}
|
||||
.energyCostChart .titleBar {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
color: white;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
color: white;
|
||||
}
|
||||
.energyCostChart .titleBar h2 {
|
||||
margin: 0;
|
||||
font-size: 18px;
|
||||
line-height: 32px;
|
||||
letter-spacing: 1.2px;
|
||||
color: #52fff8;
|
||||
}
|
||||
.graphBaseDesc {
|
||||
margin: 0 12px;
|
||||
line-height: 1;
|
||||
color: #76fff9;
|
||||
flex: 1;
|
||||
margin: 0;
|
||||
font-size: 18px;
|
||||
line-height: 32px;
|
||||
letter-spacing: 1.2px;
|
||||
color: #52fff8;
|
||||
}
|
||||
|
||||
.energyCostChart .titleBar .legend {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.energyCostChart .titleBar .legend * {
|
||||
font-size: 14px;
|
||||
line-height: 14px;
|
||||
color: #dff1fe;
|
||||
font-size: 14px;
|
||||
line-height: 14px;
|
||||
color: #dff1fe;
|
||||
}
|
||||
|
||||
.energyCostChart .titleBar .legend ul {
|
||||
display: flex;
|
||||
margin: 0;
|
||||
margin-left: 8px;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
margin: 0;
|
||||
margin-left: 8px;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
align-items: center;
|
||||
}
|
||||
.energyCostChart .titleBar .legend ul li {
|
||||
position: relative;
|
||||
margin: 4px;
|
||||
padding-left: 16px;
|
||||
position: relative;
|
||||
margin: 4px;
|
||||
padding-left: 16px;
|
||||
}
|
||||
.energyCostChart .titleBar .legend ul li::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 2px;
|
||||
top: 2px;
|
||||
display: inline-block;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
border-radius: 2px;
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 2px;
|
||||
top: 2px;
|
||||
display: inline-block;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.energyCostChart .titleBar .legend ul li:first-child::before {
|
||||
background-color: #ffd160;
|
||||
background-color: #ffd160;
|
||||
}
|
||||
|
||||
.energyCostChart .titleBar .legend ul li:nth-child(2)::before {
|
||||
background-color: #12fff5;
|
||||
background-color: #12fff5;
|
||||
}
|
||||
|
||||
.energyCostChart .titleBar .legend ul li:nth-child(3)::before {
|
||||
background-color: #2760ff;
|
||||
background-color: #2760ff;
|
||||
}
|
||||
|
||||
.radioGroup * {
|
||||
border: none !important;
|
||||
border-radius: 0 !important;
|
||||
}
|
||||
.radioGroupShort * {
|
||||
border: none !important;
|
||||
border-radius: 6px !important;
|
||||
border: none !important;
|
||||
border-radius: 0 !important;
|
||||
}
|
||||
.radioGroup *:focus-within {
|
||||
box-shadow: none !important;
|
||||
box-shadow: none !important;
|
||||
}
|
||||
|
||||
.radioGroup *::before {
|
||||
width: 0 !important;
|
||||
width: 0 !important;
|
||||
}
|
||||
|
||||
.radioGroup_button_wrapper {
|
||||
color: #fff !important;
|
||||
background: #03233c !important;
|
||||
color: #fff !important;
|
||||
background: #03233c !important;
|
||||
}
|
||||
|
||||
.radioGroup_button_wrapper.ant-radio-button-wrapper-checked {
|
||||
background: #02457e !important;
|
||||
background: #02457e !important;
|
||||
}
|
||||
|
@ -1,22 +1,33 @@
|
||||
import cls from "./index.module.scss";
|
||||
import Container from "../../Container";
|
||||
import TechSplitline from "../TechSplitline";
|
||||
import EnergyCostChart from "./EnergyCostChart";
|
||||
import EnergyCostRealtime from "./EnergeCostRealtime";
|
||||
import cls from './index.module.scss';
|
||||
import Container from '../../Container';
|
||||
import TechSplitline from '../TechSplitline';
|
||||
import EnergyCostChart from './EnergyCostChart';
|
||||
|
||||
function EnergyCost(props) {
|
||||
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>922kWh</span>
|
||||
</div>
|
||||
<div className={cls.info__item_groups}>
|
||||
<div className={cls.info__item}>水 耗 量 : 32Km³</div>
|
||||
<div className={cls.info__item}>天 然 气 I : 83m³</div>
|
||||
<div className={cls.info__item}>电 耗 量 : 52kWh</div>
|
||||
<div className={cls.info__item}>天 然 气 II: 32m³</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
return (
|
||||
<Container title="能耗" icon="battery" className={cls.energyCost}>
|
||||
<div className={`flex flex-col`}>
|
||||
<EnergyCostRealtime />
|
||||
<TechSplitline />
|
||||
|
||||
<TechSplitline />
|
||||
|
||||
<EnergyCostChart />
|
||||
</div>
|
||||
</Container>
|
||||
);
|
||||
<EnergyCostChart />
|
||||
</div>
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
|
||||
export default EnergyCost;
|
||||
|
@ -2,7 +2,7 @@
|
||||
background: url(../../../assets/energy.png) no-repeat;
|
||||
background-size: 100% 100%;
|
||||
width: 626px;
|
||||
height: 460px;
|
||||
height: 400px;
|
||||
}
|
||||
|
||||
.cost__info {
|
||||
@ -18,9 +18,12 @@
|
||||
border-radius: 2px;
|
||||
color: hsl(0, 0%, 100%, 0.9);
|
||||
box-shadow: inset 0 0 17px 0px hsla(0, 0%, 100%, 0.15);
|
||||
font-size: 14px;
|
||||
// width: 288px;
|
||||
height: 43px;
|
||||
font-size: 20px;
|
||||
letter-spacing: 1.43px;
|
||||
line-height: 40px;
|
||||
padding-left: 12px;
|
||||
text-align: center;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
|
@ -1,20 +1,46 @@
|
||||
import GraphBase from "../../Common/GraphBase";
|
||||
import "./index.module.scss";
|
||||
import { useSelector } from "react-redux";
|
||||
|
||||
import { ScrollBoard } from "@jiaminghi/data-view-react";
|
||||
|
||||
function getRandomRow() {
|
||||
const idx = Math.ceil(Math.random() * 100);
|
||||
return [idx, `${idx}#风机`, Math.ceil(Math.random() * 2) - 1];
|
||||
}
|
||||
|
||||
function getRandomRows(rows) {
|
||||
return Array(rows)
|
||||
.fill(0)
|
||||
.map(() => getRandomRow());
|
||||
}
|
||||
|
||||
// let data = [
|
||||
// [1, '1#风机', 1], // 1 正常 2 故障 0 离线
|
||||
// [2, '2#风机', 1],
|
||||
// [3, '3#风机', 1],
|
||||
// [4, '4#风机', 0],
|
||||
// [5, '5#风机', 1],
|
||||
// [6, '6#风机', 1],
|
||||
// [7, '7#风机', 0],
|
||||
// [8, '8#风机', 1],
|
||||
// [9, '9#风机', 1],
|
||||
// [10, '10#风机', 1],
|
||||
// ];
|
||||
|
||||
// let header = ['序号', '风机名称', '故障情况'];
|
||||
|
||||
function attachStyle(data) {
|
||||
return data.map((arr) => {
|
||||
return arr.map((item, index) => {
|
||||
if (index == arr.length - 1) {
|
||||
return `<div style="display: flex; align-items: center">
|
||||
<span style="box-shadow: 0 0 4px 4px ${
|
||||
item == 1 ? "#2760ff55" : item == 0 ? "#a81b2655" : "#E6A23C55"
|
||||
item == 1 ? "#2760ff55" : "#a81b2655"
|
||||
}; margin-right: 8px; width: 8px; height: 8px; border-radius: 8px; background: ${
|
||||
item == 1 ? "#2760ff" : item == 0 ? "#a81b26" : "#E6A23C"
|
||||
}"></span><span style="color: ${
|
||||
item == 1 ? "#2760ff" : item == 0 ? "#a81b26" : "#E6A23C"
|
||||
}">${item == 1 ? "运行" : item == 0 ? "故障" : "未运行"}</span></div>`;
|
||||
item == 1 ? "#2760ff" : "#a81b26"
|
||||
}"></span><span style="color: ${item == 1 ? "#2760ff" : "#a81b26"}">${
|
||||
item == 1 ? "正常" : "故障"
|
||||
}</span></div>`;
|
||||
}
|
||||
return `<span style='color: #fffa'>${item}</span>`;
|
||||
});
|
||||
@ -23,17 +49,7 @@ function attachStyle(data) {
|
||||
|
||||
function FanInfo(props) {
|
||||
const rowNum = props.rows || 8;
|
||||
// 默认使用风机信息,可以使用 source 来调整该组件使用 annealFanInfo 的数据
|
||||
const fanInfo = useSelector((state) => state[props.source ?? "fanInfo"].data);
|
||||
|
||||
const data = Object.keys(fanInfo).map((key, index) => {
|
||||
return [
|
||||
index + 1,
|
||||
key,
|
||||
fanInfo[key] == "运行" ? 1 : fanInfo[key] == "故障" ? 0 : 2,
|
||||
];
|
||||
});
|
||||
const dataRight = [...data.slice(rowNum), ...data.slice(0, rowNum)];
|
||||
let data = getRandomRows(100);
|
||||
|
||||
let config = {
|
||||
headerBGC: "rgba(4, 44, 76, 0.3)",
|
||||
@ -44,10 +60,11 @@ function FanInfo(props) {
|
||||
],
|
||||
oddRowBGC: "#042444",
|
||||
evenRowBGC: "#042c4c",
|
||||
// columnWidth: data.length > 12 ? [50, 136] : [88, 256],
|
||||
columnWidth: [50, 136],
|
||||
columnWidth: [70, 96],
|
||||
rowNum,
|
||||
hoverPause: true,
|
||||
// headerHeight: 40,
|
||||
hoverPause: false,
|
||||
// data: replaceStyle(data, 0.7),
|
||||
data: attachStyle(data),
|
||||
};
|
||||
|
||||
@ -61,9 +78,7 @@ function FanInfo(props) {
|
||||
className="flex"
|
||||
style={{
|
||||
display: "flex",
|
||||
flex: 1,
|
||||
gap: "20px",
|
||||
// gap: data.length > 12 ? "20px" : 0,
|
||||
height: "100%",
|
||||
position: "relative",
|
||||
}}
|
||||
@ -71,15 +86,9 @@ function FanInfo(props) {
|
||||
<div className="flex-1" style={{ flex: 1 }}>
|
||||
<ScrollBoard
|
||||
config={config}
|
||||
style={{
|
||||
width: "280px",
|
||||
// width: data.length > 12 ? "280px" : "100%",
|
||||
height: "100%",
|
||||
}}
|
||||
style={{ width: "280px", height: "100%" }}
|
||||
/>
|
||||
</div>
|
||||
{/* {data.length > 12 && (
|
||||
<> */}
|
||||
<div
|
||||
className="verticalLine"
|
||||
style={{
|
||||
@ -94,12 +103,10 @@ function FanInfo(props) {
|
||||
></div>
|
||||
<div className="flex-1" style={{ flex: 1 }}>
|
||||
<ScrollBoard
|
||||
config={{ ...config, data: attachStyle(dataRight) }}
|
||||
config={config}
|
||||
style={{ width: "280px", height: "100%" }}
|
||||
/>
|
||||
</div>
|
||||
{/* </>
|
||||
)} */}
|
||||
</div>
|
||||
</GraphBase>
|
||||
);
|
||||
|
@ -1,248 +0,0 @@
|
||||
import GraphBase from "../GraphBase";
|
||||
import "./index.module.scss";
|
||||
import { useSelector } from "react-redux";
|
||||
import { ScrollBoard } from "@jiaminghi/data-view-react";
|
||||
import { useMemo } from "react";
|
||||
|
||||
function attachStyle(data) {
|
||||
return data.map((arr) => {
|
||||
return arr.map((item, index) => {
|
||||
if (index == arr.length - 1) {
|
||||
return `<div style="display: flex; align-items: center">
|
||||
<span style="box-shadow: 0 0 4px 4px ${
|
||||
item == 1 ? "#2760ff55" : item == 0 ? "#a81b2655" : "#E6A23C55"
|
||||
}; margin-right: 8px; width: 8px; height: 8px; border-radius: 8px; background: ${
|
||||
item == 1 ? "#2760ff" : item == 0 ? "#a81b26" : "#E6A23C"
|
||||
}"></span><span style="color: ${
|
||||
item == 1 ? "#2760ff" : item == 0 ? "#a81b26" : "#E6A23C"
|
||||
}">${item == 1 ? "运行" : item == 0 ? "故障" : "未运行"}</span></div>`;
|
||||
}
|
||||
return `<span style='color: #fffa'>${item}</span>`;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function FanInfo(props) {
|
||||
// 默认使用风机信息,可以使用 source 来调整该组件使用 annealFanInfo 的数据
|
||||
const fanInfo = useSelector((state) => state[props.source ?? "fanInfo"].data);
|
||||
|
||||
const data = Object.keys(fanInfo).map((key, index) => {
|
||||
return [
|
||||
index + 1,
|
||||
key,
|
||||
fanInfo[key] == "运行" ? 1 : fanInfo[key] == "故障" ? 0 : 2,
|
||||
];
|
||||
});
|
||||
|
||||
const y61 = useMemo(
|
||||
() => data.filter((item) => item[1].startsWith("1#")) || [],
|
||||
[data]
|
||||
);
|
||||
const y62 = useMemo(
|
||||
() => data.filter((item) => item[1].startsWith("2#")) || [],
|
||||
[data]
|
||||
);
|
||||
const y63 = useMemo(
|
||||
() => data.filter((item) => item[1].startsWith("3#")) || [],
|
||||
[data]
|
||||
);
|
||||
const y64 = useMemo(
|
||||
() => data.filter((item) => item[1].startsWith("4#")) || [],
|
||||
[data]
|
||||
);
|
||||
const y65 = useMemo(
|
||||
() => data.filter((item) => item[1].startsWith("5#")) || [],
|
||||
[data]
|
||||
);
|
||||
const y66 = useMemo(() => [...y65.slice(5), ...y65.slice(0, 5)], [y65]);
|
||||
|
||||
let config = {
|
||||
headerBGC: "rgba(4, 44, 76, 0.3)",
|
||||
header: [
|
||||
'<span style="color:#fff">序号<span/>',
|
||||
'<span style="color:#fff">风机名称<span/>',
|
||||
'<span style="color:#fff">故障情况<span/>',
|
||||
],
|
||||
oddRowBGC: "#042444",
|
||||
evenRowBGC: "#042c4c",
|
||||
// columnWidth: data.length > 12 ? [50, 136] : [88, 256],
|
||||
columnWidth: [50, 136],
|
||||
rowNum: 6,
|
||||
hoverPause: true,
|
||||
data: [],
|
||||
};
|
||||
|
||||
return (
|
||||
<GraphBase
|
||||
icon="kiln"
|
||||
title="风机信息"
|
||||
size={props.longBg ? ["middle", "full"] : ["middle", "short"]}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
display: "grid",
|
||||
gridTemplateRows: "auto 2px auto 2px auto",
|
||||
gap: "4px",
|
||||
// height: "100%",
|
||||
position: "relative",
|
||||
}}
|
||||
>
|
||||
<div className="" style={{ display: "flex", gap: "8px" }}>
|
||||
<div>
|
||||
<h1
|
||||
style={{
|
||||
fontSize: "16px",
|
||||
fontWeight: 400,
|
||||
textAlign: "center",
|
||||
letterSpacing: "2px",
|
||||
color: "#fff",
|
||||
background: "#012041",
|
||||
padding: "4px 0",
|
||||
}}
|
||||
>
|
||||
产线Y61
|
||||
</h1>
|
||||
<ScrollBoard
|
||||
key="y61"
|
||||
config={{ ...config, data: attachStyle(y61) }}
|
||||
style={{
|
||||
width: "280px",
|
||||
height: "280px",
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<h1
|
||||
style={{
|
||||
fontSize: "16px",
|
||||
fontWeight: 400,
|
||||
textAlign: "center",
|
||||
letterSpacing: "2px",
|
||||
color: "#fff",
|
||||
background: "#012041",
|
||||
padding: "4px 0",
|
||||
}}
|
||||
>
|
||||
产线Y62
|
||||
</h1>
|
||||
<ScrollBoard
|
||||
key="y62"
|
||||
config={{ ...config, data: attachStyle(y62) }}
|
||||
style={{
|
||||
width: "280px",
|
||||
height: "280px",
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
className="horizontalLine"
|
||||
style={{
|
||||
height: "2px",
|
||||
background:
|
||||
"radial-gradient(ellipse, #15E8F563, #15E8F599, transparent, transparent)",
|
||||
}}
|
||||
></div>
|
||||
|
||||
<div className="" style={{ display: "flex", gap: "8px" }}>
|
||||
<div>
|
||||
<h1
|
||||
style={{
|
||||
fontSize: "16px",
|
||||
fontWeight: 400,
|
||||
textAlign: "center",
|
||||
letterSpacing: "2px",
|
||||
color: "#fff",
|
||||
background: "#012041",
|
||||
padding: "4px 0",
|
||||
}}
|
||||
>
|
||||
产线Y63
|
||||
</h1>
|
||||
<ScrollBoard
|
||||
key="y63"
|
||||
config={{ ...config, data: attachStyle(y63) }}
|
||||
style={{
|
||||
width: "280px",
|
||||
height: "280px",
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
{/* <div style={{ display: "flex", flexDirection: "column" }}> */}
|
||||
<h1
|
||||
style={{
|
||||
fontSize: "16px",
|
||||
fontWeight: 400,
|
||||
textAlign: "center",
|
||||
letterSpacing: "2px",
|
||||
color: "#fff",
|
||||
background: "#012041",
|
||||
padding: "4px 0",
|
||||
}}
|
||||
>
|
||||
产线Y64
|
||||
</h1>
|
||||
<ScrollBoard
|
||||
key="y64"
|
||||
config={{ ...config, data: attachStyle(y64) }}
|
||||
style={{
|
||||
width: "280px",
|
||||
height: "280px",
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
className="horizontalLine"
|
||||
style={{
|
||||
height: "2px",
|
||||
background:
|
||||
"radial-gradient(ellipse, #15E8F563, #15E8F599, transparent, transparent)",
|
||||
}}
|
||||
></div>
|
||||
|
||||
<div
|
||||
className=""
|
||||
style={{ height: "240px", display: "flex", flexDirection: "column" }}
|
||||
>
|
||||
<h1
|
||||
style={{
|
||||
fontSize: "16px",
|
||||
fontWeight: 400,
|
||||
textAlign: "center",
|
||||
letterSpacing: "2px",
|
||||
color: "#fff",
|
||||
background: "#012041",
|
||||
padding: "4px 0",
|
||||
}}
|
||||
>
|
||||
产线Y65
|
||||
</h1>
|
||||
<div style={{ flex: 1, height: "1px", display: "flex", gap: "4px" }}>
|
||||
<ScrollBoard
|
||||
key="y65"
|
||||
config={{ ...config, data: attachStyle(y65), rowNum: 5 }}
|
||||
style={{
|
||||
width: "280px",
|
||||
height: "220px",
|
||||
}}
|
||||
/>
|
||||
<ScrollBoard
|
||||
key="y66"
|
||||
config={{ ...config, data: attachStyle(y66), rowNum: 5 }}
|
||||
style={{
|
||||
width: "280px",
|
||||
height: "220px",
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</GraphBase>
|
||||
);
|
||||
}
|
||||
|
||||
export default FanInfo;
|
@ -1,50 +0,0 @@
|
||||
.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,71 +1,20 @@
|
||||
// FanRunFrequence
|
||||
import cls from "./index.module.css";
|
||||
import ReactECharts from "echarts-for-react";
|
||||
import * as echarts from "echarts";
|
||||
import { Switch } from "antd";
|
||||
import GraphBase from "../../Common/GraphBase";
|
||||
import { useState } from "react";
|
||||
import { useSelector } from "react-redux";
|
||||
import { useState, useContext } from "react";
|
||||
// import SocketContext from '../../../store/socket-data-provider';
|
||||
|
||||
function WindFrequence(props) {
|
||||
const [showChart, setShowChart] = useState(false);
|
||||
const runState = useSelector((state) => state.fanFrequence.runtime);
|
||||
const hisState = useSelector((state) => state.fanFrequence.history);
|
||||
const [showChart, setShowChart] = useState(true);
|
||||
// const { runState, hisState } = useContext(SocketContext);
|
||||
|
||||
const [options, dataList] = getOptions(showChart, hisState, runState);
|
||||
const runState = null;
|
||||
const hisState = null;
|
||||
|
||||
function handleSwitchChange(val) {
|
||||
if (val) {
|
||||
setShowChart(true);
|
||||
} else {
|
||||
setShowChart(false);
|
||||
}
|
||||
}
|
||||
return (
|
||||
<GraphBase
|
||||
icon="smoke"
|
||||
title="风机运行频率"
|
||||
size={["middle", "long"]}
|
||||
switchOptions={false}
|
||||
switchPosition={[null, 200]} // [top, left]
|
||||
onSwitch={handleSwitchChange}
|
||||
>
|
||||
<div className={cls.chart}>
|
||||
{/* {showChart && (
|
||||
<ReactECharts option={options} style={{ height: "100%" }} />
|
||||
)} */}
|
||||
{!showChart && (
|
||||
<div className={cls.gridList}>
|
||||
{dataList.map((item) => (
|
||||
<div
|
||||
key={item.id}
|
||||
className={cls.listItem}
|
||||
style={{ padding: props.stretch ? "16px 0" : "" }}
|
||||
>
|
||||
<span className={cls.fanName}>{item.name}</span>
|
||||
<span
|
||||
className={cls.fanValue}
|
||||
style={{
|
||||
fontWeight: 700,
|
||||
letterSpacing: 1,
|
||||
fontSize: 16,
|
||||
// color: "#e03537",
|
||||
color: "#24aebb",
|
||||
}}
|
||||
>
|
||||
{item.value}
|
||||
</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</GraphBase>
|
||||
);
|
||||
}
|
||||
|
||||
export default WindFrequence;
|
||||
|
||||
function getOptions(showChart, hisState, runState) {
|
||||
let dataList = null;
|
||||
let dataList = [];
|
||||
let seriesData = [];
|
||||
const colors = [
|
||||
"#12FFF5",
|
||||
@ -80,15 +29,20 @@ function getOptions(showChart, hisState, runState) {
|
||||
let options = null;
|
||||
if (showChart) {
|
||||
// keys() 结果不是按照顺序,需要 sort()
|
||||
seriesData =
|
||||
hisState != null
|
||||
? Object.keys(hisState)
|
||||
.sort()
|
||||
.map((key) => hisState[key])
|
||||
: Array(8)
|
||||
.fill(1)
|
||||
.map((_) => Array(7).fill(0));
|
||||
seriesData = hisState?.combustionAir
|
||||
? Object.keys(hisState.combustionAir)
|
||||
.sort()
|
||||
.map((key) => hisState.combustionAir[key])
|
||||
: Array(8)
|
||||
.fill(1)
|
||||
.map((_) => Array(7).fill(0));
|
||||
|
||||
// debug
|
||||
console.log(
|
||||
"助燃风 chart series data",
|
||||
hisState?.combustionAir,
|
||||
seriesData
|
||||
);
|
||||
options = {
|
||||
color: colors,
|
||||
grid: { top: 32, right: 12, bottom: 20, left: 48 },
|
||||
@ -150,10 +104,9 @@ function getOptions(showChart, hisState, runState) {
|
||||
symbol: "circle",
|
||||
areaStyle: {
|
||||
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
||||
// i % 8 避免超过8个数据时无颜色的问题
|
||||
{ offset: 0, color: colors[i % 8] + "40" },
|
||||
{ offset: 0.5, color: colors[i % 8] + "20" },
|
||||
{ offset: 1, color: colors[i % 8] + "00" },
|
||||
{ offset: 0, color: colors[i] + "40" },
|
||||
{ offset: 0.5, color: colors[i] + "20" },
|
||||
{ offset: 1, color: colors[i] + "00" },
|
||||
]),
|
||||
},
|
||||
})),
|
||||
@ -162,32 +115,80 @@ function getOptions(showChart, hisState, runState) {
|
||||
},
|
||||
};
|
||||
} else {
|
||||
dataList =
|
||||
runState != null
|
||||
? Object.keys(runState).map((fan) => ({
|
||||
id: Math.random(),
|
||||
name: fan,
|
||||
value: (+runState[fan])?.toFixed(2),
|
||||
}))
|
||||
: [
|
||||
{ id: 1, name: "1#风机", value: "0m³/h" },
|
||||
{ id: 2, name: "2#风机", value: "0m³/h" },
|
||||
{ id: 3, name: "3#风机", value: "0m³/h" },
|
||||
{ id: 4, name: "4#风机", value: "0m³/h" },
|
||||
{ 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" },
|
||||
{ id: 9, name: "9#风机", value: "0m³/h" },
|
||||
{ id: 10, name: "10#风机", value: "0m³/h" },
|
||||
{ id: 11, name: "11#风机", value: "0m³/h" },
|
||||
{ id: 12, name: "12#风机", value: "0m³/h" },
|
||||
{ id: 13, name: "13#风机", value: "0m³/h" },
|
||||
{ id: 14, name: "14#风机", value: "0m³/h" },
|
||||
{ id: 15, name: "15#风机", value: "0m³/h" },
|
||||
{ id: 16, name: "16#风机", value: "0m³/h" },
|
||||
];
|
||||
dataList = runState?.combustionAirPressureArr
|
||||
? [
|
||||
{ id: 1, name: "1#风机", value: "0m³/h" },
|
||||
{ id: 2, name: "2#风机", value: "0m³/h" },
|
||||
{ id: 3, name: "3#风机", value: "0m³/h" },
|
||||
{ id: 4, name: "4#风机", value: "0m³/h" },
|
||||
{ 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" },
|
||||
{ id: 9, name: "9#风机", value: "0m³/h" },
|
||||
{ id: 10, name: "10#风机", value: "0m³/h" },
|
||||
{ id: 11, name: "11#风机", value: "0m³/h" },
|
||||
{ id: 12, name: "12#风机", value: "0m³/h" },
|
||||
{ id: 13, name: "13#风机", value: "0m³/h" },
|
||||
{ id: 14, name: "14#风机", value: "0m³/h" },
|
||||
{ id: 15, name: "15#风机", value: "0m³/h" },
|
||||
{ id: 16, name: "16#风机", value: "0m³/h" },
|
||||
].map((item, index) => ({
|
||||
...item,
|
||||
value: runState.combustionAirPressureArr[index] ?? "/",
|
||||
}))
|
||||
: [
|
||||
{ id: 1, name: "1#风机", value: "0m³/h" },
|
||||
{ id: 2, name: "2#风机", value: "0m³/h" },
|
||||
{ id: 3, name: "3#风机", value: "0m³/h" },
|
||||
{ id: 4, name: "4#风机", value: "0m³/h" },
|
||||
{ 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" },
|
||||
{ id: 9, name: "9#风机", value: "0m³/h" },
|
||||
{ id: 10, name: "10#风机", value: "0m³/h" },
|
||||
{ id: 11, name: "11#风机", value: "0m³/h" },
|
||||
{ id: 12, name: "12#风机", value: "0m³/h" },
|
||||
{ id: 13, name: "13#风机", value: "0m³/h" },
|
||||
{ id: 14, name: "14#风机", value: "0m³/h" },
|
||||
{ id: 15, name: "15#风机", value: "0m³/h" },
|
||||
{ id: 16, name: "16#风机", value: "0m³/h" },
|
||||
];
|
||||
}
|
||||
|
||||
return [options, dataList];
|
||||
function handleSwitchChange(val) {
|
||||
if (val) {
|
||||
setShowChart(true);
|
||||
} else {
|
||||
setShowChart(false);
|
||||
}
|
||||
}
|
||||
return (
|
||||
<GraphBase
|
||||
icon="kiln"
|
||||
title="风机运行频率"
|
||||
size={["middle", "long"]}
|
||||
switchOptions={true}
|
||||
switchPosition={[null, 200]} // [top, left]
|
||||
onSwitch={handleSwitchChange}
|
||||
>
|
||||
<div className={cls.chart}>
|
||||
{showChart && (
|
||||
<ReactECharts option={options} style={{ height: "100%" }} />
|
||||
)}
|
||||
{!showChart && (
|
||||
<div className={cls.gridList}>
|
||||
{dataList.map((item) => (
|
||||
<div key={item.id} className={cls.listItem}>
|
||||
{item.name}: {item.value}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</GraphBase>
|
||||
);
|
||||
}
|
||||
|
||||
export default WindFrequence;
|
||||
|
@ -1,52 +1,33 @@
|
||||
.chart {
|
||||
height: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.gridList {
|
||||
margin-top: 12px;
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
/* grid-auto-row: ; */
|
||||
gap: 6px;
|
||||
margin-top: 12px;
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
/* grid-auto-row: ; */
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.listItem {
|
||||
border-radius: 2px;
|
||||
padding: 10px 0;
|
||||
text-align: center;
|
||||
color: #fff;
|
||||
box-shadow: inset 0 0 16px 4px rgba(255, 255, 255, 0.197);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
border-radius: 2px;
|
||||
padding: 9px 0;
|
||||
text-align: center;
|
||||
color: #fff;
|
||||
box-shadow: inset 0 0 16px 4px rgba(255, 255, 255, 0.197);
|
||||
}
|
||||
|
||||
.headWidget {
|
||||
position: absolute;
|
||||
top: 22px;
|
||||
right: 24px;
|
||||
height: 32px;
|
||||
width: 410px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
color: #fff;
|
||||
position: absolute;
|
||||
top: 22px;
|
||||
right: 24px;
|
||||
height: 32px;
|
||||
width: 410px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
color: #fff;
|
||||
}
|
||||
.relative {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.flex {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.fanName {
|
||||
text-align: right;
|
||||
flex: 7;
|
||||
}
|
||||
|
||||
.fanValue {
|
||||
flex: 3;
|
||||
text-align: left;
|
||||
position: relative;
|
||||
}
|
||||
|
@ -1,16 +0,0 @@
|
||||
.feeder {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.feeder-running {
|
||||
background: url(../../../assets/online.png);
|
||||
background-size: 100% 100%;
|
||||
}
|
||||
.feeder-stop {
|
||||
background: url(../../../assets/offline.png);
|
||||
background-size: 100% 100%;
|
||||
}
|
||||
.feeder-error {
|
||||
background: url(../../../assets/offline.png);
|
||||
background-size: 100% 100%;
|
||||
}
|
@ -1,104 +0,0 @@
|
||||
import { useSelector } from "react-redux";
|
||||
import { motion } from "framer-motion";
|
||||
import "./feeder.css";
|
||||
|
||||
function FeederStatus(props) {
|
||||
const feeder = useSelector((state) => state.feeder);
|
||||
const rightFeeder = feeder.rightFeeder;
|
||||
const leftFeeder = feeder.leftFeeder;
|
||||
return (
|
||||
<motion.div
|
||||
className="feeder"
|
||||
style={{
|
||||
position: "absolute",
|
||||
bottom: "56px",
|
||||
left: "740px",
|
||||
width: "400px",
|
||||
height: "128px",
|
||||
zIndex: "-1",
|
||||
display: "flex",
|
||||
gap: "8px",
|
||||
paddingTop: "12px",
|
||||
justifyContent: "center",
|
||||
...props.style,
|
||||
}}
|
||||
animate={{
|
||||
opacity: [0, 0, 0, 0.6, 1],
|
||||
transition: { duration: 0.3, delay: 2 },
|
||||
}}
|
||||
>
|
||||
<span
|
||||
style={{
|
||||
position: "absolute",
|
||||
color: "#6be1e1",
|
||||
top: "-32px",
|
||||
left: "20px",
|
||||
fontSize: "22px",
|
||||
}}
|
||||
>
|
||||
1#投料{" "}
|
||||
<b
|
||||
style={{
|
||||
fontWeight: 400,
|
||||
color:
|
||||
leftFeeder == "故障"
|
||||
? "#f83a35"
|
||||
: leftFeeder == "运行"
|
||||
? "#9af72b"
|
||||
: "#ccc",
|
||||
}}
|
||||
>
|
||||
{leftFeeder}
|
||||
</b>
|
||||
</span>
|
||||
<span
|
||||
style={{
|
||||
position: "absolute",
|
||||
color: "#6be1e1",
|
||||
top: "-32px",
|
||||
left: "230px",
|
||||
fontSize: "22px",
|
||||
}}
|
||||
>
|
||||
2#投料{" "}
|
||||
<b
|
||||
style={{
|
||||
fontWeight: 400,
|
||||
color:
|
||||
rightFeeder == "故障"
|
||||
? "#f83a35"
|
||||
: rightFeeder == "运行"
|
||||
? "#9af72b"
|
||||
: "#ccc",
|
||||
}}
|
||||
>
|
||||
{rightFeeder}
|
||||
</b>
|
||||
</span>
|
||||
<span
|
||||
className={`
|
||||
feeder ${
|
||||
leftFeeder == "运行"
|
||||
? "feeder-running"
|
||||
: leftFeeder == "故障"
|
||||
? "feeder-error"
|
||||
: "feeder-stop"
|
||||
}
|
||||
`}
|
||||
></span>
|
||||
<span
|
||||
className={`
|
||||
feeder ${
|
||||
rightFeeder == "运行"
|
||||
? "feeder-running"
|
||||
: rightFeeder == "故障"
|
||||
? "feeder-error"
|
||||
: "feeder-stop"
|
||||
}
|
||||
`}
|
||||
></span>
|
||||
</motion.div>
|
||||
);
|
||||
}
|
||||
|
||||
export default FeederStatus;
|
@ -1,223 +1,187 @@
|
||||
// 助燃风流量
|
||||
import cls from "./index.module.css";
|
||||
import BottomBarItem from "../BottomItemBackground";
|
||||
import ReactECharts from "echarts-for-react";
|
||||
import * as echarts from "echarts";
|
||||
import { Switch } from "antd";
|
||||
import { useState, useEffect } from "react";
|
||||
import { useSelector, useDispatch } from "react-redux";
|
||||
import dayjs from "dayjs";
|
||||
import cls from './index.module.css';
|
||||
import BottomBarItem from '../BottomItemBackground';
|
||||
import ReactECharts from 'echarts-for-react';
|
||||
import * as echarts from 'echarts';
|
||||
import { randomInt } from '../../../utils';
|
||||
import { Switch } from 'antd';
|
||||
import { useState, useContext } from 'react';
|
||||
// import SocketContext from '../../../store/socket-data-provider';
|
||||
|
||||
/** 助燃风流量 */
|
||||
function GasI(props) {
|
||||
const [showChart, setShowChart] = useState(true);
|
||||
const runState = useSelector((state) => state.combustionAir.runtime);
|
||||
const hisState = useSelector((state) => state.combustionAir.history);
|
||||
const [showChart, setShowChart] = useState(true);
|
||||
// const { runState, hisState } = useContext(SocketContext);
|
||||
|
||||
let [options, dataList] = getOptions(showChart, hisState, runState);
|
||||
const runState = null;
|
||||
const hisState = null;
|
||||
|
||||
function handleSwitchChange(val) {
|
||||
if (val) {
|
||||
setShowChart(true);
|
||||
} else {
|
||||
setShowChart(false);
|
||||
}
|
||||
}
|
||||
let dataList = [];
|
||||
let seriesData = [];
|
||||
const colors = [
|
||||
'#12FFF5',
|
||||
'#2760FF',
|
||||
'#FFD160',
|
||||
'#E80091',
|
||||
'#8064ff',
|
||||
'#ff8a3b',
|
||||
'#8cd26d',
|
||||
'#2aa1ff',
|
||||
];
|
||||
let options = null;
|
||||
if (showChart) {
|
||||
// keys() 结果不是按照顺序,需要 sort()
|
||||
seriesData = hisState?.combustionAir
|
||||
? Object.keys(hisState.combustionAir)
|
||||
.sort()
|
||||
.map((key) => hisState.combustionAir[key])
|
||||
: Array(8)
|
||||
.fill(1)
|
||||
.map((_) => Array(7).fill(0));
|
||||
|
||||
const desc =
|
||||
dayjs().subtract(7, "day").format("YYYY.MM.DD") +
|
||||
" - " +
|
||||
dayjs().subtract(1, "day").format("YYYY.MM.DD");
|
||||
// debug
|
||||
console.log(
|
||||
'助燃风 chart series data',
|
||||
hisState?.combustionAir,
|
||||
seriesData,
|
||||
);
|
||||
options = {
|
||||
color: colors,
|
||||
grid: { top: 32, 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³',
|
||||
nameTextStyle: {
|
||||
color: '#fff',
|
||||
fontSize: 10,
|
||||
align: 'right',
|
||||
},
|
||||
type: 'value',
|
||||
axisLabel: {
|
||||
color: '#fff',
|
||||
fontSize: 12,
|
||||
},
|
||||
axisLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
color: '#213259',
|
||||
},
|
||||
},
|
||||
splitLine: {
|
||||
lineStyle: {
|
||||
color: '#213259a0',
|
||||
},
|
||||
},
|
||||
// interval: 10,
|
||||
// min: 0,
|
||||
// max: 100,
|
||||
},
|
||||
series: seriesData.map((v, i) => ({
|
||||
name: i + 1 + '#助燃风',
|
||||
data: v,
|
||||
type: 'line',
|
||||
symbol: 'circle',
|
||||
areaStyle: {
|
||||
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
||||
{ offset: 0, color: colors[i] + '40' },
|
||||
{ offset: 0.5, color: colors[i] + '20' },
|
||||
{ offset: 1, color: colors[i] + '00' },
|
||||
]),
|
||||
},
|
||||
})),
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
},
|
||||
};
|
||||
} else {
|
||||
dataList = runState?.combustionAirPressureArr
|
||||
? [
|
||||
{ id: 1, name: '1#助燃风', value: '0m³/h' },
|
||||
{ id: 2, name: '2#助燃风', value: '0m³/h' },
|
||||
{ id: 3, name: '3#助燃风', value: '0m³/h' },
|
||||
{ id: 4, name: '4#助燃风', value: '0m³/h' },
|
||||
{ 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] ?? '/',
|
||||
}))
|
||||
: [
|
||||
{ id: 1, name: '1#助燃风', value: '0m³/h' },
|
||||
{ id: 2, name: '2#助燃风', value: '0m³/h' },
|
||||
{ id: 3, name: '3#助燃风', value: '0m³/h' },
|
||||
{ id: 4, name: '4#助燃风', value: '0m³/h' },
|
||||
{ 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);
|
||||
}
|
||||
|
||||
return (
|
||||
<BottomBarItem
|
||||
icon="pause"
|
||||
title="助燃风流量"
|
||||
desc={desc}
|
||||
className={cls.gas}
|
||||
style={props.style}
|
||||
>
|
||||
<div className={cls.headWidget}>
|
||||
<div className="flex items-center">
|
||||
<Switch size="small" defaultChecked onChange={handleSwitchChange} />
|
||||
{showChart && <span className={cls.switchLabel}>历史详情</span>}
|
||||
{!showChart && <span className={cls.switchLabel}>实时流量</span>}
|
||||
</div>
|
||||
</div>
|
||||
function handleSwitchChange(val) {
|
||||
if (val) {
|
||||
setShowChart(true);
|
||||
} else {
|
||||
setShowChart(false);
|
||||
}
|
||||
}
|
||||
return (
|
||||
<BottomBarItem
|
||||
icon="pause"
|
||||
title="助燃风流量"
|
||||
className={cls.gas}
|
||||
style={props.style}
|
||||
>
|
||||
<div className={cls.headWidget}>
|
||||
<div className="flex items-center">
|
||||
<Switch size="small" defaultChecked onChange={handleSwitchChange} />
|
||||
{showChart && <span className={cls.switchLabel}>历史详情</span>}
|
||||
{!showChart && <span className={cls.switchLabel}>实时流量</span>}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className={cls.chart}>
|
||||
{showChart && (
|
||||
<ReactECharts option={options} style={{ height: "100%" }} />
|
||||
)}
|
||||
{!showChart && (
|
||||
<div className={cls.gridList}>
|
||||
{dataList.map((item) => (
|
||||
<div key={item.id} className={cls.listItem}>
|
||||
<span className={cls.item_label}>{item.name}</span>
|
||||
<span className={cls.item_value}>{item.value}</span>
|
||||
{/* {item.name}: {item.value} */}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</BottomBarItem>
|
||||
);
|
||||
<div className={cls.chart}>
|
||||
{showChart && (
|
||||
<ReactECharts option={options} style={{ height: '100%' }} />
|
||||
)}
|
||||
{!showChart && (
|
||||
<div className={cls.gridList}>
|
||||
{dataList.map((item) => (
|
||||
<div key={item.id} className={cls.listItem}>
|
||||
{item.name}: {item.value}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</BottomBarItem>
|
||||
);
|
||||
}
|
||||
|
||||
export default GasI;
|
||||
|
||||
function getOptions(showChart, hisState, runState) {
|
||||
const colors = [
|
||||
"#12FFF5",
|
||||
"#2760FF",
|
||||
"#FFD160",
|
||||
"#E80091",
|
||||
"#8064ff",
|
||||
"#ff8a3b",
|
||||
"#8cd26d",
|
||||
"#2aa1ff",
|
||||
];
|
||||
let seriesData = null;
|
||||
let dataList = null;
|
||||
let options = null;
|
||||
|
||||
if (showChart) {
|
||||
// keys() 结果不是按照顺序,需要 sort()
|
||||
seriesData =
|
||||
hisState != null
|
||||
? Object.keys(hisState)
|
||||
.sort()
|
||||
.map((key) => hisState[key])
|
||||
: Array(8)
|
||||
.fill(1)
|
||||
.map((_) => Array(7).fill(0));
|
||||
|
||||
options = {
|
||||
color: colors,
|
||||
grid: { top: 36, 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)
|
||||
.fill(1)
|
||||
.map((_, index) => {
|
||||
const today = new Date();
|
||||
const dtimestamp = today - (index + 1) * 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,
|
||||
},
|
||||
axisLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
color: "#213259",
|
||||
},
|
||||
},
|
||||
splitLine: {
|
||||
lineStyle: {
|
||||
color: "#213259a0",
|
||||
},
|
||||
},
|
||||
// interval: 10,
|
||||
// min: 0,
|
||||
// max: 100,
|
||||
},
|
||||
series: seriesData.map((v, i) => ({
|
||||
name: i + 1 + "#流量",
|
||||
data: v,
|
||||
type: "line",
|
||||
symbol: "circle",
|
||||
symbolSize: 6,
|
||||
// label: {
|
||||
// show: true,
|
||||
// position: "top",
|
||||
// distance: 10,
|
||||
// color: "#fffc",
|
||||
// },
|
||||
areaStyle: {
|
||||
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
||||
{ offset: 0, color: colors[i % colors.length] + "40" },
|
||||
{ offset: 0.5, color: colors[i % colors.length] + "20" },
|
||||
{ offset: 1, color: colors[i % colors.length] + "00" },
|
||||
]),
|
||||
},
|
||||
})),
|
||||
tooltip: {
|
||||
trigger: "axis",
|
||||
axisPointer: {
|
||||
type: "shadow",
|
||||
},
|
||||
className: "xc-chart-tooltip",
|
||||
// backgroundColor: ''
|
||||
},
|
||||
};
|
||||
} else {
|
||||
dataList =
|
||||
runState != null
|
||||
? [
|
||||
{ id: 1, name: "1#助燃风流量", value: "0m³/h" },
|
||||
{ id: 2, name: "2#助燃风流量", value: "0m³/h" },
|
||||
{ id: 3, name: "3#助燃风流量", value: "0m³/h" },
|
||||
{ id: 4, name: "4#助燃风流量", value: "0m³/h" },
|
||||
{ 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[index] ?? "/",
|
||||
}))
|
||||
: [
|
||||
{ id: 1, name: "1#助燃风流量", value: "0m³/h" },
|
||||
{ id: 2, name: "2#助燃风流量", value: "0m³/h" },
|
||||
{ id: 3, name: "3#助燃风流量", value: "0m³/h" },
|
||||
{ id: 4, name: "4#助燃风流量", value: "0m³/h" },
|
||||
{ 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" },
|
||||
];
|
||||
}
|
||||
|
||||
return [options, dataList];
|
||||
}
|
||||
|
@ -26,10 +26,9 @@
|
||||
position: absolute;
|
||||
/* background: #00ee33; */
|
||||
top: 20px;
|
||||
left: 180px;
|
||||
right: 24px;
|
||||
height: 32px;
|
||||
width: 128px;
|
||||
width: 190px;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
@ -63,21 +62,7 @@
|
||||
padding: 12px 0;
|
||||
text-align: center;
|
||||
color: #fff;
|
||||
box-shadow: inset 0 0 12px 2px rgba(255, 255, 255, 0.197);
|
||||
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.item_label {
|
||||
flex: 5;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.item_value {
|
||||
flex: 4;
|
||||
text-align: left;
|
||||
box-shadow: inset 0 0 16px 4px rgba(255, 255, 255, 0.197);
|
||||
}
|
||||
|
||||
.headWidget {
|
||||
|
@ -1,138 +1,124 @@
|
||||
// TODO: 通用组件 - 按钮 菜单控制层
|
||||
import useIcon from "../../../hooks/useIcon";
|
||||
import cls from "./index.module.css";
|
||||
import { useMemo, useState } from "react";
|
||||
import { Switch, Select } from "antd";
|
||||
import "./selector.style.overwrite.css";
|
||||
import triangle from "../../../assets/Icon/triangle.svg";
|
||||
import useIcon from '../../../hooks/useIcon';
|
||||
import cls from './index.module.css';
|
||||
import { useMemo, useState } from 'react';
|
||||
import { Switch, Radio } from 'antd';
|
||||
|
||||
function choseBg(size) {
|
||||
const [width, height] = size;
|
||||
return width === "long" && height === "middle"
|
||||
? "long-middle"
|
||||
: width === "long" && height === "short"
|
||||
? "long-short"
|
||||
: width === "short" && height === "middle"
|
||||
? "short-middle"
|
||||
: width === "short" && height === "short"
|
||||
? "short-short"
|
||||
: width === "short" && height === "long"
|
||||
? "short-long"
|
||||
: width === "middle" && height === "middle"
|
||||
? "middle-middle"
|
||||
: width === "middle" && height === "short"
|
||||
? "middle-short"
|
||||
: width === "middle" && height === "long"
|
||||
? "middle-long"
|
||||
: width === "middle" && height === "full"
|
||||
? "middle-full"
|
||||
: "middle-middle";
|
||||
const [width, height] = size;
|
||||
return width === 'long' && height === 'middle'
|
||||
? 'long-middle'
|
||||
: width === 'long' && height === 'short'
|
||||
? 'long-short'
|
||||
: width === 'short' && height === 'middle'
|
||||
? 'short-middle'
|
||||
: width === 'short' && height === 'short'
|
||||
? 'short-short'
|
||||
: width === 'short' && height === 'long'
|
||||
? 'short-long'
|
||||
: width === 'middle' && height === 'middle'
|
||||
? 'middle-middle'
|
||||
: width === 'middle' && height === 'short'
|
||||
? 'middle-short'
|
||||
: width === 'middle' && height === 'long'
|
||||
? 'middle-long'
|
||||
: width === 'middle' && height === 'full'
|
||||
? 'middle-full'
|
||||
: 'middle-middle';
|
||||
}
|
||||
|
||||
function GraphBase(props) {
|
||||
const size = props.size || ["middle", "middle"];
|
||||
const bgClass = choseBg(size);
|
||||
const {
|
||||
icon,
|
||||
title,
|
||||
desc,
|
||||
switchOptions,
|
||||
onSwitch,
|
||||
dateOptions,
|
||||
onDateChange,
|
||||
defaultSelect,
|
||||
selectWidth,
|
||||
legend,
|
||||
} = props;
|
||||
const iconSrc = useIcon(icon);
|
||||
const colors = useMemo(() => ["#ffd160", "#2760ff", "#15e8f5"], []);
|
||||
const [showChart, setShowChart] = useState(true);
|
||||
const size = props.size || ['middle', 'middle'];
|
||||
const bgClass = choseBg(size);
|
||||
const {
|
||||
icon,
|
||||
title,
|
||||
desc,
|
||||
switchOptions,
|
||||
onSwitch,
|
||||
dateOptions,
|
||||
onDateChange,
|
||||
legend,
|
||||
} = props;
|
||||
const iconSrc = useIcon(icon);
|
||||
const colors = useMemo(() => ['#ffd160', '#2760ff', '#15e8f5'], []);
|
||||
const [showChart, setShowChart] = useState(true);
|
||||
|
||||
let dto = null;
|
||||
const switchStyle = {};
|
||||
let dto = null;
|
||||
const switchStyle = {};
|
||||
|
||||
if (props.switchPosition) {
|
||||
props.switchPosition.forEach((item, index) => {
|
||||
if (item != null) {
|
||||
switchStyle[index == 0 ? "top" : "left"] = item + "px";
|
||||
}
|
||||
});
|
||||
}
|
||||
if (props.switchPosition) {
|
||||
props.switchPosition.forEach((item, index) => {
|
||||
if (item != null) {
|
||||
switchStyle[index == 0 ? 'top' : 'left'] = item + 'px';
|
||||
}
|
||||
});
|
||||
}
|
||||
if (dateOptions) {
|
||||
dto = dateOptions.map((item) => (
|
||||
<Radio.Button value={item} key={item} className="radio-group__item">
|
||||
{item}
|
||||
</Radio.Button>
|
||||
));
|
||||
}
|
||||
|
||||
if (dateOptions) {
|
||||
dto = (
|
||||
<Select
|
||||
defaultValue={defaultSelect || dateOptions[0]}
|
||||
style={{ width: selectWidth || 60 }}
|
||||
popupClassName="xc-date-selector-menu"
|
||||
className={cls.graphBaseDate + " " + cls.radioGroup}
|
||||
options={dateOptions.map((item) => ({ label: item, value: item }))}
|
||||
suffixIcon={<img src={triangle} alt="#" />}
|
||||
notFoundContent={
|
||||
<span
|
||||
style={{
|
||||
color: "#fff",
|
||||
fontSize: "14px",
|
||||
lineHeight: 1,
|
||||
paddingLeft: "12px",
|
||||
}}
|
||||
>
|
||||
- 无 -
|
||||
</span>
|
||||
}
|
||||
onChange={(value, option) => onDateChange(value)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
function handleSwitchChange(v) {
|
||||
v ? setShowChart(true) : setShowChart(false);
|
||||
onSwitch(v);
|
||||
}
|
||||
|
||||
function handleSwitchChange(v) {
|
||||
v ? setShowChart(true) : setShowChart(false);
|
||||
onSwitch(v);
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
className={
|
||||
"graph-base " +
|
||||
cls[bgClass] +
|
||||
" " +
|
||||
cls.graphBase +
|
||||
" " +
|
||||
props.className
|
||||
}
|
||||
style={{ ...props.style }}
|
||||
>
|
||||
<div className={cls.graphBaseTitle}>
|
||||
<img src={iconSrc} alt="#" />
|
||||
<h2>{title}</h2>
|
||||
{desc && <div className={cls.graphBaseDesc}>{desc}</div>}
|
||||
</div>
|
||||
<div className={cls.graphBaseContent}>
|
||||
{switchOptions && (
|
||||
<div className={cls.graphBaseSwitch} style={switchStyle}>
|
||||
<Switch size="small" defaultChecked onChange={handleSwitchChange} />
|
||||
{showChart && <span className={cls.switchLabel}>历史详情</span>}
|
||||
{!showChart && <span className={cls.switchLabel}>实时流量</span>}
|
||||
</div>
|
||||
)}
|
||||
{legend && showChart && (
|
||||
<div className={cls.legend}>
|
||||
{legend.map((item, index) => (
|
||||
<div className={cls.legendItem} key={item}>
|
||||
<span
|
||||
className={cls.lengedItemPrefix}
|
||||
style={{ backgroundColor: colors[index] }}
|
||||
></span>
|
||||
<span className={cls.legendItemLabel}>{item}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
{dateOptions && dto}
|
||||
{props.children}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
return (
|
||||
<div
|
||||
className={
|
||||
'graph-base ' +
|
||||
cls[bgClass] +
|
||||
' ' +
|
||||
cls.graphBase +
|
||||
' ' +
|
||||
props.className
|
||||
}
|
||||
style={{ ...props.style }}
|
||||
>
|
||||
<div className={cls.graphBaseTitle}>
|
||||
<img src={iconSrc} alt="#" />
|
||||
<h2>{title}</h2>
|
||||
</div>
|
||||
<div className={cls.graphBaseContent}>
|
||||
{desc && <div className={cls.graphBaseDesc}>{desc}</div>}
|
||||
{switchOptions && (
|
||||
<div className={cls.graphBaseSwitch} style={switchStyle}>
|
||||
<Switch size="small" defaultChecked onChange={handleSwitchChange} />
|
||||
{showChart && <span className={cls.switchLabel}>历史详情</span>}
|
||||
{!showChart && <span className={cls.switchLabel}>实时流量</span>}
|
||||
</div>
|
||||
)}
|
||||
{legend && showChart && (
|
||||
<div className={cls.legend}>
|
||||
{legend.map((item, index) => (
|
||||
<div className={cls.legendItem} key={item}>
|
||||
<span
|
||||
className={cls.lengedItemPrefix}
|
||||
style={{ backgroundColor: colors[index] }}
|
||||
></span>
|
||||
<span className={cls.legendItemLabel}>{item}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
{dateOptions && (
|
||||
<Radio.Group
|
||||
defaultValue={dateOptions[0]}
|
||||
buttonStyle="solid"
|
||||
className={cls.graphBaseDate + ' ' + cls.radioGroup}
|
||||
onChange={({ target }) => onDateChange(target.value)}
|
||||
>
|
||||
{dto}
|
||||
</Radio.Group>
|
||||
)}
|
||||
{props.children}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default GraphBase;
|
||||
|
@ -63,7 +63,7 @@
|
||||
}
|
||||
|
||||
.graphBaseTitle > img {
|
||||
width: 24px;
|
||||
width: 20px;
|
||||
}
|
||||
|
||||
.graphBaseTitle > h2 {
|
||||
@ -72,7 +72,7 @@
|
||||
'Source Han Sans SC', 'Noto Sans CJK SC', 'WenQuanYi Micro Hei', sans-serif;
|
||||
margin: 0;
|
||||
margin-left: 6px;
|
||||
font-size: 22px;
|
||||
font-size: 20px;
|
||||
color: #fff;
|
||||
letter-spacing: 2px;
|
||||
font-weight: 500;
|
||||
@ -85,10 +85,9 @@
|
||||
}
|
||||
|
||||
.graphBaseDesc {
|
||||
margin-left: 8px;
|
||||
/* position: absolute;
|
||||
position: absolute;
|
||||
top: 25px;
|
||||
left: 150px; */
|
||||
left: 150px;
|
||||
font-size: 19px;
|
||||
color: #76fff9;
|
||||
}
|
||||
@ -115,7 +114,7 @@
|
||||
|
||||
.radioGroup * {
|
||||
border: none !important;
|
||||
border-radius: 6px !important;
|
||||
border-radius: 0 !important;
|
||||
}
|
||||
|
||||
.radioGroup *:focus-within {
|
||||
|
@ -1,31 +0,0 @@
|
||||
.xc-date-selector-menu {
|
||||
background-color: #04233c !important;
|
||||
}
|
||||
|
||||
.xc-date-selector-menu .ant-select-item {
|
||||
color: #fff;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.xc-date-selector-menu .ant-select-item-option-content {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.xc-date-selector-menu .ant-select-item-option-selected {
|
||||
color: #fff !important;
|
||||
background-color: #02457E !important;
|
||||
}
|
||||
|
||||
.ant-select-selector {
|
||||
background-color: #02457E !important;
|
||||
color: #fff !important;
|
||||
}
|
||||
/*
|
||||
.ant-select-selector::after {
|
||||
content: '\25BC' !important;
|
||||
visibility: visible !important;
|
||||
position: absolute;
|
||||
top: 2px;
|
||||
right: 22px;
|
||||
color: #04233c;
|
||||
} */
|
@ -1,24 +1,60 @@
|
||||
import cls from "./kiln.module.scss";
|
||||
import Container from "../../Container";
|
||||
import { useSelector } from "react-redux";
|
||||
import { useEffect } from "react";
|
||||
import { useSelector, useDispatch } from "react-redux";
|
||||
import { stateNameMap } from "../../../store/features/kilnSlice";
|
||||
|
||||
export default function Kiln() {
|
||||
const kilnInfo = useSelector((state) => state.kiln);
|
||||
const dispatch = useDispatch();
|
||||
console.log("state: ", kilnInfo, stateNameMap);
|
||||
|
||||
const infos = Object.keys(kilnInfo).map((key) => ({
|
||||
label: stateNameMap[key],
|
||||
value: kilnInfo[key],
|
||||
}));
|
||||
|
||||
useEffect(() => {
|
||||
setInterval(() => {
|
||||
dispatch({
|
||||
type: "kiln/setKilnInfo",
|
||||
payload: {
|
||||
kilnPressure: Math.ceil(Math.random() * 100) + "Pa",
|
||||
waterTemp: Math.ceil(Math.random() * 100) + "℃",
|
||||
waterFlow: Math.ceil(Math.random() * 100) + "m³/h",
|
||||
waterPressure: Math.ceil(Math.random() * 100) + "Pa",
|
||||
combustionAirPressure: Math.ceil(Math.random() * 100) + "Pa",
|
||||
topTemp: Math.ceil(Math.random() * 100) + "℃",
|
||||
compressedAirPressure: Math.ceil(Math.random() * 100) + "Pa",
|
||||
meltTemp: Math.ceil(Math.random() * 100) + "℃",
|
||||
},
|
||||
});
|
||||
}, 30000);
|
||||
}, []);
|
||||
|
||||
// const infos = [
|
||||
// { label: "窑炉压力", value: ctx?.runState?.kilnPressure || "0Pa" },
|
||||
// { label: "循环水温度", value: ctx?.runState?.waterTemp || "0℃" },
|
||||
// { label: "循环水流量", value: ctx?.runState?.waterFlow || "0㎡/h" },
|
||||
// { label: "循环水压力", value: ctx?.runState?.waterPressure || "0Pa" },
|
||||
// {
|
||||
// label: "助燃风压力",
|
||||
// value: ctx?.runState?.combustionAirPressure || "0℃",
|
||||
// },
|
||||
// { label: "碹顶加权温度", value: ctx?.runState?.topTemp || "0℃" },
|
||||
// {
|
||||
// label: "压缩气压力",
|
||||
// value: ctx?.runState?.compressedAirPressure || "0Pa",
|
||||
// },
|
||||
// { label: "融化加权温度", value: ctx?.runState?.meltTemp || "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}>
|
||||
<span className={cls.label}>{item.label}</span>
|
||||
<span className={cls.value}>{item.value}</span>
|
||||
{/* {item.label}: {item.value} */}
|
||||
{item.label}: {item.value}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
@ -24,19 +24,6 @@
|
||||
line-height: 40px;
|
||||
text-align: center;
|
||||
user-select: none;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
|
||||
.label {
|
||||
flex: 6;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.value {
|
||||
flex: 4;
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,105 +1,98 @@
|
||||
import * as echarts from "echarts";
|
||||
import { randomInt } from "../../../../utils";
|
||||
import * as echarts from 'echarts';
|
||||
import { randomInt } from '../../../../utils';
|
||||
|
||||
export default function getOptions(seriesData, name) {
|
||||
const colors = [
|
||||
"#12FFF5",
|
||||
"#2760FF",
|
||||
"#FFD160",
|
||||
"#E80091",
|
||||
"#8064ff",
|
||||
"#ff8a3b",
|
||||
"#8cd26d",
|
||||
"#2aa1ff",
|
||||
];
|
||||
return {
|
||||
color: colors,
|
||||
grid: { top: 38, 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)
|
||||
.fill(1)
|
||||
.map((_, index) => {
|
||||
const today = new Date();
|
||||
const dtimestamp = today - (index+1) * 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",
|
||||
},
|
||||
},
|
||||
},
|
||||
series: seriesData.map((arr, index) => ({
|
||||
name: index + 1 + "#" + name,
|
||||
data: arr,
|
||||
type: "line",
|
||||
symbol: 'circle',
|
||||
symbolSize: 6,
|
||||
areaStyle: {
|
||||
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
||||
{ offset: 0, color: colors[index] + "40" },
|
||||
{ offset: 0.5, color: colors[index] + "20" },
|
||||
{ offset: 1, color: colors[index] + "00" },
|
||||
]),
|
||||
},
|
||||
})),
|
||||
tooltip: {
|
||||
trigger: "axis",
|
||||
axisPointer: {
|
||||
type: "shadow",
|
||||
},
|
||||
className: "xc-chart-tooltip",
|
||||
// backgroundColor: ''
|
||||
},
|
||||
};
|
||||
const colors = [
|
||||
'#12FFF5',
|
||||
'#2760FF',
|
||||
'#FFD160',
|
||||
'#E80091',
|
||||
'#8064ff',
|
||||
'#ff8a3b',
|
||||
'#8cd26d',
|
||||
'#2aa1ff',
|
||||
];
|
||||
return {
|
||||
color: colors,
|
||||
grid: { top: 38, 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)
|
||||
.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',
|
||||
},
|
||||
},
|
||||
},
|
||||
series: seriesData.map((arr, index) => ({
|
||||
name: index + 1 + '#' + name,
|
||||
data: arr,
|
||||
type: 'line',
|
||||
areaStyle: {
|
||||
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
||||
{ offset: 0, color: colors[index] + '40' },
|
||||
{ offset: 0.5, color: colors[index] + '20' },
|
||||
{ offset: 1, color: colors[index] + '00' },
|
||||
]),
|
||||
},
|
||||
})),
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
},
|
||||
};
|
||||
}
|
||||
|
@ -1,31 +1,37 @@
|
||||
import cls from "./index.module.css";
|
||||
import ReactECharts from "echarts-for-react";
|
||||
import getOptions from "./chart.config";
|
||||
import { useSelector, useDispatch } from "react-redux";
|
||||
import cls from './index.module.css';
|
||||
import ReactECharts from 'echarts-for-react';
|
||||
import getOptions from './chart.config';
|
||||
// import SocketContext from '../../../../store/socket-data-provider';
|
||||
import { useContext } from 'react';
|
||||
|
||||
function GasChart(props) {
|
||||
const { dataSource } = props;
|
||||
const hisState = useSelector((state) => state.natGas.history);
|
||||
const dataName = dataSource == "gas-i" ? "gasIHistory" : "gasIIHistory";
|
||||
const { dataSource } = props;
|
||||
// const { hisState } = useContext(SocketContext);
|
||||
const hisState = null;
|
||||
const dataName = dataSource == 'gas-i' ? 'kilnGasT1' : 'kilnGasT2';
|
||||
|
||||
const seriesData = hisState?.[dataName]
|
||||
? Object.keys(hisState?.[dataName])
|
||||
.sort()
|
||||
.map((key, index) => hisState?.[dataName][key])
|
||||
: Array(dataSource == "gas-i" ? 8 : 4).fill(Array(7).fill(0));
|
||||
// keys() 的结果不是按照顺序的,需要 sort()
|
||||
const seriesData = hisState?.[dataName]
|
||||
? Object.keys(hisState?.[dataName])
|
||||
.sort()
|
||||
.map((key, index) => hisState?.[dataName][key])
|
||||
: Array(dataSource == 'gas-i' ? 8 : 4).fill(Array(7).fill(0));
|
||||
|
||||
return (
|
||||
<div className={cls.gasChart}>
|
||||
<ReactECharts
|
||||
key={dataSource}
|
||||
option={getOptions(
|
||||
seriesData,
|
||||
dataSource == "gas-i" ? "天然气I" : "天然气II"
|
||||
)}
|
||||
style={{ height: "100%" }}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
// debug
|
||||
console.log('天然气 series data', dataName, hisState?.[dataName], seriesData);
|
||||
|
||||
return (
|
||||
<div className={cls.gasChart}>
|
||||
<ReactECharts
|
||||
key={Math.random()}
|
||||
option={getOptions(
|
||||
seriesData,
|
||||
dataSource == 'gas-i' ? '天然气I' : '天然气II',
|
||||
)}
|
||||
style={{ height: '100%' }}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default GasChart;
|
||||
|
@ -1,58 +1,55 @@
|
||||
import cls from "./index.module.css";
|
||||
import { useSelector } from "react-redux";
|
||||
import cls from './index.module.css';
|
||||
import { useContext, useEffect, useState } from 'react';
|
||||
// import SocketContext from '../../../../store/socket-data-provider';
|
||||
|
||||
function getData(type) {
|
||||
let data = [];
|
||||
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" },
|
||||
];
|
||||
break;
|
||||
case "gas-ii":
|
||||
data = [
|
||||
{ id: 11, name: "1#天然气II", value: "0m³/h" },
|
||||
{ id: 12, name: "2#天然气II", value: "0m³/h" },
|
||||
{ id: 13, name: "3#天然气II", value: "0m³/h" },
|
||||
{ id: 14, name: "4#天然气II", value: "0m³/h" },
|
||||
// { id: 15, name: '5#天然气II', value: '0m³/h' },
|
||||
];
|
||||
break;
|
||||
}
|
||||
return data;
|
||||
let data = [];
|
||||
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' },
|
||||
];
|
||||
break;
|
||||
case 'gas-ii':
|
||||
data = [
|
||||
{ id: 11, name: '1#天然气II', value: '0m³/h' },
|
||||
{ id: 12, name: '2#天然气II', value: '0m³/h' },
|
||||
{ id: 13, name: '3#天然气II', value: '0m³/h' },
|
||||
{ id: 14, name: '4#天然气II', value: '0m³/h' },
|
||||
// { id: 15, name: '5#天然气II', value: '0m³/h' },
|
||||
];
|
||||
break;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
function GridList(props) {
|
||||
const runState = useSelector((state) => state.natGas.runtime);
|
||||
// const { runState } = useContext(SocketContext);
|
||||
const runState = null;
|
||||
|
||||
const key = props.dataSource == 'gas-i' ? 'gasFlowArr' : 'furnaceGasFlowArr';
|
||||
|
||||
const key = props.dataSource == "gas-i" ? "gasIRuntime" : "gasIIRuntime";
|
||||
let dataList = getData(props.dataSource);
|
||||
dataList = runState?.[key]
|
||||
? dataList.map((v, i) => ({ ...v, value: runState[key][i] ?? '/' }))
|
||||
: dataList;
|
||||
|
||||
let dataList = getData(props.dataSource);
|
||||
dataList = runState?.[key]
|
||||
? dataList.map((v, i) => ({
|
||||
...v,
|
||||
value: (runState[key][i] || 0) + "m³/h",
|
||||
}))
|
||||
: dataList;
|
||||
|
||||
return (
|
||||
<div className={cls.gridList}>
|
||||
{dataList.map((item) => (
|
||||
<div key={item.id} className={cls.listItem}>
|
||||
<span className={cls.item_label}>{item.name}</span>
|
||||
<span className={cls.item_value}>{item.value}</span>
|
||||
{/* {item.name}: {item.value} */}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
return (
|
||||
<div className={cls.gridList}>
|
||||
{dataList.map((item) => (
|
||||
<div key={item.id} className={cls.listItem}>
|
||||
{item.name}: {item.value}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default GridList;
|
||||
|
@ -1,27 +1,14 @@
|
||||
.gridList {
|
||||
margin-top: 12px;
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 8px;
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.listItem {
|
||||
border-radius: 2px;
|
||||
padding: 12px 0;
|
||||
text-align: center;
|
||||
color: #fff;
|
||||
box-shadow: inset 0 0 16px 4px rgba(255, 255, 255, 0.197);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.item_label {
|
||||
flex: 5;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.item_value {
|
||||
flex: 6;
|
||||
text-align: left;
|
||||
color: #fff;
|
||||
box-shadow: inset 0 0 16px 4px rgba(255, 255, 255, 0.197);
|
||||
}
|
||||
|
@ -1,109 +1,71 @@
|
||||
// 天然气流量
|
||||
import cls from "./index.module.css";
|
||||
import BottomBarItem from "../BottomItemBackground";
|
||||
import triangle from "../../../assets/Icon/triangle.svg";
|
||||
import { Switch, Select, Radio } from "antd";
|
||||
import { useState } from "react";
|
||||
import GridList from "./gridList";
|
||||
import GasChart from "./gasChart";
|
||||
import dayjs from "dayjs";
|
||||
import cls from './index.module.css';
|
||||
import BottomBarItem from '../BottomItemBackground';
|
||||
|
||||
import { Switch, Radio } from 'antd';
|
||||
import { useState } from 'react';
|
||||
import GridList from './gridList';
|
||||
import GasChart from './gasChart';
|
||||
|
||||
function GasII(props) {
|
||||
const [dataSource, setDataSource] = useState("gas-i"); // gas-i , gas-ii
|
||||
const [showChart, setShowChart] = useState(true);
|
||||
const [dataSource, setDataSource] = useState('gas-i'); // gas-i , gas-ii
|
||||
const [showChart, setShowChart] = useState(true);
|
||||
|
||||
function handleSwitchChange(val) {
|
||||
if (val) {
|
||||
setShowChart(true);
|
||||
} else {
|
||||
setShowChart(false);
|
||||
}
|
||||
}
|
||||
function handleSwitchChange(val) {
|
||||
if (val) {
|
||||
setShowChart(true);
|
||||
} else {
|
||||
setShowChart(false);
|
||||
}
|
||||
}
|
||||
|
||||
// function handleSourceChange(e) {
|
||||
// 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');
|
||||
}
|
||||
}
|
||||
|
||||
function handleDateChange(value) {
|
||||
if (value == "天然气I") {
|
||||
setDataSource("gas-i");
|
||||
} else {
|
||||
setDataSource("gas-ii");
|
||||
}
|
||||
}
|
||||
return (
|
||||
<BottomBarItem
|
||||
icon="pause"
|
||||
title="天然气流量"
|
||||
className={`${cls.gas} ${props.className}`}
|
||||
style={props.style}
|
||||
>
|
||||
{/* legend */}
|
||||
<div className={cls.headWidget}>
|
||||
<div className="flex items-center">
|
||||
<Switch size="small" defaultChecked onChange={handleSwitchChange} />
|
||||
{showChart && <span className={cls.switchLabel}>历史详情</span>}
|
||||
{!showChart && <span className={cls.switchLabel}>实时流量</span>}
|
||||
</div>
|
||||
|
||||
const desc =
|
||||
dayjs().subtract(7, "day").format("YYYY.MM.DD") +
|
||||
" - " +
|
||||
dayjs().subtract(1, "day").format("YYYY.MM.DD");
|
||||
return (
|
||||
<BottomBarItem
|
||||
icon="pause"
|
||||
title="天然气流量"
|
||||
desc={desc}
|
||||
className={`${cls.gas} ${props.className}`}
|
||||
style={props.style}
|
||||
>
|
||||
{/* legend */}
|
||||
<div className={cls.headWidget}>
|
||||
<div className="flex items-center">
|
||||
<Switch size="small" defaultChecked onChange={handleSwitchChange} />
|
||||
{showChart && <span className={cls.switchLabel}>历史详情</span>}
|
||||
{!showChart && <span className={cls.switchLabel}>实时流量</span>}
|
||||
</div>
|
||||
<Radio.Group
|
||||
defaultValue="i"
|
||||
buttonStyle="solid"
|
||||
className={cls.radioGroup}
|
||||
onChange={handleSourceChange}
|
||||
>
|
||||
<Radio.Button value="i" className="radio-group__item">
|
||||
天然气 I
|
||||
</Radio.Button>
|
||||
<Radio.Button value="ii" className="radio-group__item">
|
||||
天然气 II
|
||||
</Radio.Button>
|
||||
</Radio.Group>
|
||||
</div>
|
||||
|
||||
<Select
|
||||
defaultValue={"天然气I"}
|
||||
style={{ width: 90 }}
|
||||
popupClassName="xc-date-selector-menu"
|
||||
className={cls.radioGroup}
|
||||
options={["天然气I", "天然气II"].map((item) => ({
|
||||
label: item,
|
||||
value: item,
|
||||
}))}
|
||||
suffixIcon={<img src={triangle} alt="#" />}
|
||||
notFoundContent={
|
||||
<span
|
||||
style={{
|
||||
color: "#fff",
|
||||
fontSize: "14px",
|
||||
lineHeight: 1,
|
||||
paddingLeft: "12px",
|
||||
}}
|
||||
>
|
||||
- 无 -
|
||||
</span>
|
||||
}
|
||||
onChange={(value, option) => handleDateChange(value)}
|
||||
/>
|
||||
|
||||
{/* <Radio.Group
|
||||
defaultValue="i"
|
||||
buttonStyle="solid"
|
||||
className={cls.radioGroup}
|
||||
onChange={handleSourceChange}
|
||||
>
|
||||
<Radio.Button value="i" className="radio-group__item">
|
||||
天然气 I
|
||||
</Radio.Button>
|
||||
<Radio.Button value="ii" className="radio-group__item">
|
||||
天然气 II
|
||||
</Radio.Button>
|
||||
</Radio.Group> */}
|
||||
</div>
|
||||
|
||||
<div className={cls.chart}>
|
||||
{showChart && <GasChart dataSource={dataSource} />}
|
||||
{!showChart && <GridList dataSource={dataSource} />}
|
||||
</div>
|
||||
</BottomBarItem>
|
||||
);
|
||||
<div className={cls.chart}>
|
||||
{showChart && <GasChart dataSource={dataSource} />}
|
||||
{!showChart && <GridList dataSource={dataSource} />}
|
||||
</div>
|
||||
</BottomBarItem>
|
||||
);
|
||||
}
|
||||
|
||||
export default GasII;
|
||||
|
@ -24,10 +24,9 @@
|
||||
.headWidget {
|
||||
position: absolute;
|
||||
top: 22px;
|
||||
left: 178px;
|
||||
right: 24px;
|
||||
height: 32px;
|
||||
width: calc(100% - 200px);
|
||||
/* background: #12fff5; */
|
||||
width: 410px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
@ -70,7 +69,7 @@
|
||||
|
||||
.radioGroup * {
|
||||
border: none !important;
|
||||
border-radius: 6px !important;
|
||||
border-radius: 0 !important;
|
||||
}
|
||||
|
||||
.radioGroup *:focus-within {
|
||||
|
@ -1,25 +1,25 @@
|
||||
import { useCallback, useEffect, useState } from "react";
|
||||
import cls from "./index.module.scss";
|
||||
import { useCallback, useState } from 'react';
|
||||
import cls from './index.module.scss';
|
||||
|
||||
export default function CenterMenu({ active, onChangeActive }) {
|
||||
const menuList = [
|
||||
["窑炉总览", "/kilnSummary"],
|
||||
["窑炉内部", "/kilnInner"],
|
||||
["退火监测", "/stopFire"],
|
||||
["质检统计", "/quailtyCheck"],
|
||||
["能耗分析", "/energyCost"],
|
||||
];
|
||||
return (
|
||||
<div className={`${cls.centerMenu} flex`}>
|
||||
{menuList.map((menu) => (
|
||||
<div
|
||||
key={menu[0]}
|
||||
className={`${cls.menuItem} ${active == menu[0] ? cls.active : ""}`}
|
||||
onClick={() => onChangeActive(menu[0])}
|
||||
>
|
||||
{menu[0]}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
const menuList = [
|
||||
['窑炉总览', '/kilnSummary'],
|
||||
['窑炉内部', '/kilnInner'],
|
||||
['退火监测', '/stopFire'],
|
||||
['质检统计', '/quailtyCheck'],
|
||||
['能耗分析', '/energyCost'],
|
||||
];
|
||||
return (
|
||||
<div className={`${cls.centerMenu} flex`}>
|
||||
{menuList.map((menu) => (
|
||||
<div
|
||||
key={menu[0]}
|
||||
className={`${cls.menuItem} ${active == menu[0] ? cls.active : ''}`}
|
||||
onClick={() => onChangeActive(menu[0])}
|
||||
>
|
||||
{menu[0]}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -1,8 +1,7 @@
|
||||
.centerMenu {
|
||||
position: fixed;
|
||||
top: 120px;
|
||||
// left: 1340px;
|
||||
left: 1460px;
|
||||
left: 1340px;
|
||||
color: white;
|
||||
z-index: 10000;
|
||||
}
|
||||
|
@ -1,24 +0,0 @@
|
||||
import { useSelector } from "react-redux";
|
||||
import cls from "../index.module.scss";
|
||||
|
||||
const SmokeHandleTable = () => {
|
||||
const smokeInfo = useSelector((state) => state.smoke?.info);
|
||||
return (
|
||||
<div className={cls.info__item_groups}>
|
||||
<div className={cls.info__item}>
|
||||
氧 气 含 量 : {(+smokeInfo?.O2_float)?.toFixed(2) || 0}%
|
||||
</div>
|
||||
<div className={cls.info__item}>
|
||||
氮氧化物浓度: {(+smokeInfo?.NOX_float)?.toFixed(2) || 0}mg/m³
|
||||
</div>
|
||||
<div className={cls.info__item}>
|
||||
二氧化硫浓度: {(+smokeInfo?.SO2_float)?.toFixed(2) || 0}mg/m³
|
||||
</div>
|
||||
<div className={cls.info__item}>
|
||||
颗粒物浓度: {(+smokeInfo?.dust_float)?.toFixed(2) || 0}mg/m³
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default SmokeHandleTable;
|
@ -1,339 +1,183 @@
|
||||
import cls from "./index.module.css";
|
||||
import * as echarts from "echarts";
|
||||
import { Select } from "antd";
|
||||
import ReactECharts from "echarts-for-react";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useSelector } from "react-redux";
|
||||
import triangle from "../../../../assets/Icon/triangle.svg";
|
||||
import dayjs from "dayjs";
|
||||
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';
|
||||
|
||||
const SmokeTrendChart = (props) => {
|
||||
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);
|
||||
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 [source, setSource] = useState("O2_float");
|
||||
const [period, setPeriod] = useState("day");
|
||||
function handleSwitchChange(val) {
|
||||
// val: boolean
|
||||
console.log('switch change', val);
|
||||
}
|
||||
|
||||
const currentTrend =
|
||||
period === "day"
|
||||
? dayTrend
|
||||
: period === "week"
|
||||
? weekTrend
|
||||
: period === "month"
|
||||
? monthTrend
|
||||
: yearTrend;
|
||||
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 options = getOptions(source, period, currentTrend);
|
||||
<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 [desc, setDesc] = useState("");
|
||||
|
||||
useEffect(() => {
|
||||
switch (period) {
|
||||
case "day":
|
||||
setDesc(
|
||||
dayjs().subtract(1, "day").format("YYYY.MM.DD") +
|
||||
" 7点 - " +
|
||||
dayjs().format("YYYY.MM.DD") +
|
||||
" 7点"
|
||||
);
|
||||
break;
|
||||
case "month":
|
||||
setDesc(
|
||||
dayjs().subtract(1, "month").format("YYYY.MM.") +
|
||||
"29 - " +
|
||||
dayjs().format("YYYY.MM.") +
|
||||
"28"
|
||||
);
|
||||
break;
|
||||
case "week":
|
||||
setDesc(
|
||||
dayjs().subtract(7, "day").format("YYYY.MM.DD") +
|
||||
" - " +
|
||||
dayjs().subtract(1, "day").format("YYYY.MM.DD")
|
||||
);
|
||||
break;
|
||||
case "year":
|
||||
setDesc(
|
||||
dayjs().subtract(1, "year").endOf("year").format("YYYY.MM.") +
|
||||
"29 - " +
|
||||
dayjs().endOf("year").format("YYYY.MM.") +
|
||||
"28"
|
||||
);
|
||||
break;
|
||||
}
|
||||
}, [period]);
|
||||
|
||||
function handleDateChange(value) {
|
||||
setPeriod(
|
||||
{
|
||||
日: "day",
|
||||
周: "week",
|
||||
月: "month",
|
||||
年: "year",
|
||||
}[value]
|
||||
);
|
||||
}
|
||||
function handleSourceChange(value) {
|
||||
setSource(
|
||||
{
|
||||
氧气: "O2_float",
|
||||
氮氧化物: "NOX_float",
|
||||
二氧化硫: "SO2_float",
|
||||
颗粒物: "dust_float",
|
||||
}[value]
|
||||
);
|
||||
}
|
||||
|
||||
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> */}
|
||||
<Select
|
||||
defaultValue={"氧气"}
|
||||
style={{ width: 100 }}
|
||||
popupClassName="xc-date-selector-menu"
|
||||
className={cls.radioGroupShort}
|
||||
options={["氧气", "氮氧化物", "二氧化硫", "颗粒物"].map((item) => ({
|
||||
label: item,
|
||||
value: item,
|
||||
}))}
|
||||
suffixIcon={<img src={triangle} alt="#" />}
|
||||
notFoundContent={
|
||||
<span
|
||||
style={{
|
||||
color: "#fff",
|
||||
fontSize: "14px",
|
||||
lineHeight: 1,
|
||||
paddingLeft: "12px",
|
||||
}}
|
||||
>
|
||||
- 无 -
|
||||
</span>
|
||||
}
|
||||
onChange={(value, option) => handleSourceChange(value)}
|
||||
/>
|
||||
|
||||
<div className={cls.graphBaseDesc}>{desc}</div>
|
||||
|
||||
{/* <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> */}
|
||||
|
||||
<Select
|
||||
defaultValue={"日"}
|
||||
style={{ width: 60 }}
|
||||
popupClassName="xc-date-selector-menu"
|
||||
className={cls.radioGroupShort}
|
||||
options={["日", "周", "月", "年"].map((item) => ({
|
||||
label: item,
|
||||
value: item,
|
||||
}))}
|
||||
suffixIcon={<img src={triangle} alt="#" />}
|
||||
notFoundContent={
|
||||
<span
|
||||
style={{
|
||||
color: "#fff",
|
||||
fontSize: "14px",
|
||||
lineHeight: 1,
|
||||
paddingLeft: "12px",
|
||||
}}
|
||||
>
|
||||
- 无 -
|
||||
</span>
|
||||
}
|
||||
onChange={(value, option) => handleDateChange(value)}
|
||||
/>
|
||||
</div>
|
||||
{options && <ReactECharts option={options} style={{ height: "220px" }} />}
|
||||
{!options && (
|
||||
<p
|
||||
style={{
|
||||
color: "#cccf",
|
||||
fontSize: "24px",
|
||||
userSelect: "none",
|
||||
textAlign: "center",
|
||||
paddingTop: "96px",
|
||||
}}
|
||||
>
|
||||
暂无数据
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
<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>
|
||||
);
|
||||
};
|
||||
|
||||
export default SmokeTrendChart;
|
||||
|
||||
function getOptions(source, period, trend) {
|
||||
if (
|
||||
trend[source].length === 0 ||
|
||||
trend[source].filter((item) => item.value).length == 0
|
||||
)
|
||||
return null;
|
||||
|
||||
return {
|
||||
color: ["#FFD160", "#12FFF5", "#2760FF"],
|
||||
grid: {
|
||||
top: 40,
|
||||
right: 12,
|
||||
bottom: 20,
|
||||
left: source == "O2_float" ? 56 : 72,
|
||||
},
|
||||
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: source == "O2_float" ? "单位:%" : "单位mg/m³",
|
||||
nameTextStyle: {
|
||||
color: "#fff",
|
||||
fontSize: 13,
|
||||
align: "right",
|
||||
},
|
||||
type: "value",
|
||||
axisLabel: {
|
||||
color: "#fff",
|
||||
fontSize: 14,
|
||||
formatter: "{value}",
|
||||
},
|
||||
axisLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
color: "#213259",
|
||||
},
|
||||
},
|
||||
splitLine: {
|
||||
lineStyle: {
|
||||
color: "#213259a0",
|
||||
},
|
||||
},
|
||||
},
|
||||
series: [
|
||||
{
|
||||
data: trend[source].map((item) =>
|
||||
!(item.value == null || isNaN(+item.value))
|
||||
? (+item.value).toFixed(2)
|
||||
: null
|
||||
),
|
||||
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",
|
||||
axisPointer: {
|
||||
type: "shadow",
|
||||
},
|
||||
className: "xc-chart-tooltip",
|
||||
},
|
||||
};
|
||||
}
|
||||
|
@ -1,102 +1,91 @@
|
||||
.energyCostChart {
|
||||
height: 1px;
|
||||
flex: 1;
|
||||
padding-top: 8px;
|
||||
height: 1px;
|
||||
flex: 1;
|
||||
padding-top: 8px;
|
||||
}
|
||||
.energyCostChart .titleBar {
|
||||
width: 400px;
|
||||
margin-bottom: 4px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
color: white;
|
||||
width: 400px;
|
||||
margin-bottom: 4px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
color: white;
|
||||
}
|
||||
.energyCostChart .titleBar h2 {
|
||||
margin: 0;
|
||||
font-size: 18px;
|
||||
line-height: 32px;
|
||||
letter-spacing: 1.2px;
|
||||
color: #52fff8;
|
||||
margin: 0;
|
||||
font-size: 18px;
|
||||
line-height: 32px;
|
||||
letter-spacing: 1.2px;
|
||||
color: #52fff8;
|
||||
}
|
||||
|
||||
.energyCostChart .titleBar .legend {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.energyCostChart .titleBar .legend * {
|
||||
font-size: 14px;
|
||||
line-height: 14px;
|
||||
color: #dff1fe;
|
||||
font-size: 14px;
|
||||
line-height: 14px;
|
||||
color: #dff1fe;
|
||||
}
|
||||
|
||||
.energyCostChart .titleBar .legend ul {
|
||||
display: flex;
|
||||
margin: 0;
|
||||
margin-left: 8px;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
margin: 0;
|
||||
margin-left: 8px;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
align-items: center;
|
||||
}
|
||||
.energyCostChart .titleBar .legend ul li {
|
||||
position: relative;
|
||||
margin: 4px;
|
||||
padding-left: 16px;
|
||||
position: relative;
|
||||
margin: 4px;
|
||||
padding-left: 16px;
|
||||
}
|
||||
.energyCostChart .titleBar .legend ul li::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 2px;
|
||||
top: 2px;
|
||||
display: inline-block;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
border-radius: 2px;
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 2px;
|
||||
top: 2px;
|
||||
display: inline-block;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.energyCostChart .titleBar .legend ul li:first-child::before {
|
||||
background-color: #ffd160;
|
||||
background-color: #ffd160;
|
||||
}
|
||||
|
||||
.energyCostChart .titleBar .legend ul li:nth-child(2)::before {
|
||||
background-color: #12fff5;
|
||||
background-color: #12fff5;
|
||||
}
|
||||
|
||||
.energyCostChart .titleBar .legend ul li:nth-child(3)::before {
|
||||
background-color: #2760ff;
|
||||
background-color: #2760ff;
|
||||
}
|
||||
|
||||
.choiceBar {
|
||||
margin: 4px 0;
|
||||
margin: 4px 0;
|
||||
}
|
||||
|
||||
.radioGroup * {
|
||||
border: none !important;
|
||||
border-radius: 0 !important;
|
||||
}
|
||||
.radioGroupShort * {
|
||||
border: none !important;
|
||||
border-radius: 6px !important;
|
||||
border: none !important;
|
||||
border-radius: 0 !important;
|
||||
}
|
||||
.radioGroup *:focus-within {
|
||||
box-shadow: none !important;
|
||||
box-shadow: none !important;
|
||||
}
|
||||
|
||||
.radioGroup *::before {
|
||||
width: 0 !important;
|
||||
width: 0 !important;
|
||||
}
|
||||
|
||||
.radioGroup_button_wrapper {
|
||||
color: #fff !important;
|
||||
background: #03233c !important;
|
||||
color: #fff !important;
|
||||
background: #03233c !important;
|
||||
}
|
||||
|
||||
.radioGroup_button_wrapper.ant-radio-button-wrapper-checked {
|
||||
background: #02457e !important;
|
||||
}
|
||||
|
||||
.graphBaseDesc {
|
||||
margin: 0 12px;
|
||||
line-height: 1;
|
||||
color: #76fff9;
|
||||
flex: 1;
|
||||
background: #02457e !important;
|
||||
}
|
||||
|
@ -1,19 +1,23 @@
|
||||
import cls from "./index.module.scss";
|
||||
import Container from "../../Container";
|
||||
import TechSplitline from "../TechSplitline";
|
||||
import SmokeTrendChart from "./SmokeTrendChart";
|
||||
import SmokeHandleTable from "./SmokeHandleTable";
|
||||
import cls from './index.module.scss';
|
||||
import Container from '../../Container';
|
||||
import TechSplitline from '../TechSplitline';
|
||||
import SmokeTrendChart from './SmokeTrendChart';
|
||||
|
||||
function SmokeHandle(props) {
|
||||
return (
|
||||
<Container title="烟气处理" icon="smoke" className={cls.smokeHandle}>
|
||||
<div className={`${cls.smokeHandle__content} flex flex-col`}>
|
||||
<SmokeHandleTable />
|
||||
<TechSplitline />
|
||||
<SmokeTrendChart />
|
||||
</div>
|
||||
</Container>
|
||||
);
|
||||
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}>氧 气 含 量 : 72%</div>
|
||||
<div className={cls.info__item}>一氧化氮排放浓度:59mg/m³</div>
|
||||
<div className={cls.info__item}>二氧化硫排放浓度:59mg/m³</div>
|
||||
<div className={cls.info__item}>二氧化氮排放浓度:59mg/m³</div>
|
||||
</div>
|
||||
<TechSplitline />
|
||||
<SmokeTrendChart />
|
||||
</div>
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
|
||||
export default SmokeHandle;
|
||||
|
@ -3,7 +3,7 @@
|
||||
background: url(../../../assets/smoke.png) no-repeat;
|
||||
background-size: 100% 100%;
|
||||
width: 626px;
|
||||
height: 490px;
|
||||
height: 540px;
|
||||
.smokeHandle__content {
|
||||
margin-top: 8px;
|
||||
}
|
||||
@ -13,17 +13,19 @@
|
||||
border-radius: 2px;
|
||||
color: hsl(0, 0%, 100%, 0.9);
|
||||
box-shadow: inset 0 0 17px 0px hsla(0, 0%, 100%, 0.15);
|
||||
height: 32px;
|
||||
font-size: 16px;
|
||||
// width: 288px;
|
||||
height: 56px;
|
||||
font-size: 20px;
|
||||
letter-spacing: 1.43px;
|
||||
line-height: 32px;
|
||||
line-height: 56px;
|
||||
text-align: center;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.info__item_groups {
|
||||
margin-bottom: 12px;
|
||||
margin-left: 8px;
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 4px;
|
||||
gap: 8px;
|
||||
}
|
||||
|
@ -1,41 +0,0 @@
|
||||
import BlueRect from "../BlueRect";
|
||||
import { useSelector } from "react-redux";
|
||||
import { motion, AnimatePresence } from "framer-motion";
|
||||
|
||||
const blueTe = [
|
||||
"TE401",
|
||||
"TE402",
|
||||
"TE403",
|
||||
"PE401",
|
||||
"PE402",
|
||||
"PE403",
|
||||
];
|
||||
|
||||
function TemperatureBottom(props) {
|
||||
const tempBottom = useSelector((state) => state.temperature.bottom);
|
||||
|
||||
return (
|
||||
<motion.div
|
||||
className="temperature-bottom"
|
||||
style={{
|
||||
position: "absolute",
|
||||
top: "0",
|
||||
left: "0",
|
||||
width: "100%",
|
||||
height: "80vh",
|
||||
zIndex: "-1",
|
||||
...props.style
|
||||
}}
|
||||
animate={{
|
||||
opacity: [0, 0, 0, 0.6, 1],
|
||||
transition: { duration: 0.3, delay: 2 },
|
||||
}}
|
||||
>
|
||||
{Object.keys(tempBottom).map((d) => (
|
||||
<BlueRect title={d} key={d + Math.random()} value={tempBottom[d]} blue={blueTe.includes(d)} />
|
||||
))}
|
||||
</motion.div>
|
||||
);
|
||||
}
|
||||
|
||||
export default TemperatureBottom;
|
@ -1,45 +0,0 @@
|
||||
import BlueRect from "../BlueRect";
|
||||
import { useSelector } from "react-redux";
|
||||
import { motion, AnimatePresence } from "framer-motion";
|
||||
|
||||
const blueTe = [
|
||||
"TE271",
|
||||
"TE272",
|
||||
"TE273",
|
||||
"TE274",
|
||||
"TE275",
|
||||
"TE276",
|
||||
"TE277",
|
||||
"TE278",
|
||||
"TE279",
|
||||
"TE280",
|
||||
];
|
||||
|
||||
function TemperatureTop(props) {
|
||||
const tempTop = useSelector((state) => state.temperature.top);
|
||||
|
||||
return (
|
||||
<motion.div
|
||||
className="temperature-top"
|
||||
style={{
|
||||
position: "absolute",
|
||||
top: "0",
|
||||
left: "0",
|
||||
width: "100%",
|
||||
height: "80vh",
|
||||
zIndex: "-1",
|
||||
...props.style
|
||||
}}
|
||||
animate={{
|
||||
opacity: [0, 0, 0, 0.6, 1],
|
||||
transition: { duration: 0.3, delay: 2 },
|
||||
}}
|
||||
>
|
||||
{Object.keys(tempTop).map((d) => (
|
||||
<BlueRect title={d} key={d + Math.random()} value={tempTop[d]} blue={blueTe.includes(d)} />
|
||||
))}
|
||||
</motion.div>
|
||||
);
|
||||
}
|
||||
|
||||
export default TemperatureTop;
|
@ -10,15 +10,11 @@ import icon3 from "../../../assets/CenterChart2icon3.svg";
|
||||
import useTimeCounter from "../../../hooks/useTimeCounter";
|
||||
|
||||
const FireInfo = () => {
|
||||
// const dispatch = useDispatch();
|
||||
const dispatch = useDispatch();
|
||||
const fireInfo = useSelector((state) => state.fireInfo);
|
||||
const time = fireInfo.lastFireChangeTime || "0分0秒";
|
||||
const minsec = useTimeCounter(time);
|
||||
let [min, sec] = [0, 0];
|
||||
if (minsec) {
|
||||
min = minsec[0];
|
||||
sec = minsec[1];
|
||||
}
|
||||
const [min, sec] = useTimeCounter(time);
|
||||
|
||||
// useEffect(() => {
|
||||
// const restTime = ctx?.runState?.lastFireChangeTime;
|
||||
// if (restTime == null) return;
|
||||
@ -80,22 +76,22 @@ const FireInfo = () => {
|
||||
// };
|
||||
// }, [ctx?.runState?.lastFireChangeTime]);
|
||||
|
||||
// useEffect(() => {
|
||||
// setInterval(() => {
|
||||
// dispatch({
|
||||
// type: "fireInfo/setFireInfo",
|
||||
// payload: {
|
||||
// fireChangeTime: `${Math.ceil(Math.random() * 10)}:${Math.ceil(
|
||||
// Math.random() * 10
|
||||
// )}`,
|
||||
// fireDirection: Math.random * 10 < 5 ? "东火" : "西火",
|
||||
// lastFireChangeTime: `${Math.ceil(Math.random() * 60)}分${Math.ceil(
|
||||
// Math.random() * 50
|
||||
// )}秒`,
|
||||
// },
|
||||
// });
|
||||
// }, 10000);
|
||||
// }, []);
|
||||
useEffect(() => {
|
||||
setInterval(() => {
|
||||
dispatch({
|
||||
type: "fireInfo/setFireInfo",
|
||||
payload: {
|
||||
fireChangeTime: `${Math.ceil(Math.random() * 10)}:${Math.ceil(
|
||||
Math.random() * 10
|
||||
)}`,
|
||||
fireDirection: Math.random * 10 < 5 ? "东火" : "西火",
|
||||
lastFireChangeTime: `${Math.ceil(Math.random() * 60)}分${Math.ceil(
|
||||
Math.random() * 50
|
||||
)}秒`,
|
||||
},
|
||||
});
|
||||
}, 10000);
|
||||
}, []);
|
||||
|
||||
const data = [
|
||||
{
|
||||
|
@ -1 +0,0 @@
|
||||
1.json
|
@ -1,213 +1,163 @@
|
||||
import cls from "./index.module.css";
|
||||
import GraphBase from "../GraphBase";
|
||||
import ReactECharts from "echarts-for-react";
|
||||
import { useSelector } from "react-redux";
|
||||
import { useState } from "react";
|
||||
import dayjs from 'dayjs'
|
||||
import cls from './index.module.css';
|
||||
import GraphBase from '../GraphBase';
|
||||
import ReactECharts from 'echarts-for-react';
|
||||
|
||||
function FaultTotal(props) {
|
||||
const [currentSelect, setCurrentSelect] = useState("日");
|
||||
const isra = useSelector((state) => state.isra);
|
||||
const options = {
|
||||
color: [
|
||||
'#2760FF',
|
||||
'#5B9BFF',
|
||||
'#FFD160',
|
||||
'#8167F6',
|
||||
'#99D66C',
|
||||
'#FF8A40',
|
||||
'#12FFF5',
|
||||
],
|
||||
grid: { top: 42, right: 12, bottom: 20, left: 48 },
|
||||
legend: {
|
||||
top: 10,
|
||||
padding: 5,
|
||||
itemWidth: 12,
|
||||
itemHeight: 12,
|
||||
itemGap: 12,
|
||||
height: 12,
|
||||
textStyle: {
|
||||
color: '#DFF1FE',
|
||||
fontSize: 12,
|
||||
},
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
data: Array(5)
|
||||
.fill(1)
|
||||
.map((_, index) => {
|
||||
return '产线' + (index + 1);
|
||||
}),
|
||||
axisLabel: {
|
||||
color: '#fff',
|
||||
fontSize: 12,
|
||||
},
|
||||
axisTick: { show: false },
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
width: 1,
|
||||
color: '#213259',
|
||||
},
|
||||
},
|
||||
},
|
||||
yAxis: {
|
||||
name: '单位/个',
|
||||
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: [
|
||||
{
|
||||
name: '缺陷1',
|
||||
type: 'bar',
|
||||
stack: 'abcd',
|
||||
emphasis: {
|
||||
focus: 'series',
|
||||
},
|
||||
data: [320, 332, 301, 334, 390, 330, 320],
|
||||
},
|
||||
{
|
||||
name: '缺陷2',
|
||||
type: 'bar',
|
||||
stack: 'abcd',
|
||||
emphasis: {
|
||||
focus: 'series',
|
||||
},
|
||||
data: [120, 132, 101, 134, 90, 230, 210],
|
||||
},
|
||||
{
|
||||
name: '缺陷3',
|
||||
type: 'bar',
|
||||
stack: 'abcd',
|
||||
emphasis: {
|
||||
focus: 'series',
|
||||
},
|
||||
data: [220, 182, 191, 234, 290, 330, 310],
|
||||
},
|
||||
{
|
||||
name: '缺陷4',
|
||||
type: 'bar',
|
||||
stack: 'abcd',
|
||||
emphasis: {
|
||||
focus: 'series',
|
||||
},
|
||||
data: [150, 232, 201, 154, 190, 330, 410],
|
||||
},
|
||||
{
|
||||
name: '缺陷5',
|
||||
type: 'bar',
|
||||
stack: 'abcd',
|
||||
emphasis: {
|
||||
focus: 'series',
|
||||
},
|
||||
data: [862, 1018, 964, 1026, 1679, 1600, 1570],
|
||||
},
|
||||
{
|
||||
name: '缺陷6',
|
||||
type: 'bar',
|
||||
barGap: 20,
|
||||
barWidth: 12,
|
||||
stack: 'abcd',
|
||||
emphasis: {
|
||||
focus: 'series',
|
||||
},
|
||||
data: [620, 732, 701, 734, 1090, 1130, 1120],
|
||||
},
|
||||
],
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
},
|
||||
};
|
||||
|
||||
const currentStatistic =
|
||||
currentSelect == "日"
|
||||
? isra.dayStatistic
|
||||
: currentSelect == "周"
|
||||
? isra.weekStatistic
|
||||
: currentSelect == "月"
|
||||
? isra.monthStatistic
|
||||
: currentSelect == "月"
|
||||
? isra.yearStatistic
|
||||
: [];
|
||||
function handleDateChange(v) {
|
||||
console.log('date ', v);
|
||||
}
|
||||
|
||||
const series = preHandleStatisticData(currentStatistic, isra.checkType ?? []);
|
||||
const options = getOptions(series, isra, currentStatistic);
|
||||
// 根据使用的页面决定背景的大小
|
||||
const bgSize =
|
||||
props.page == 'home' ? ['middle', 'short'] : ['middle', 'long'];
|
||||
|
||||
function handleDateChange(v) {
|
||||
setCurrentSelect(v);
|
||||
}
|
||||
|
||||
// 根据使用的页面决定背景的大小
|
||||
const bgSize =
|
||||
props.page == "home" ? ["middle", "short"] : ["middle", "long"];
|
||||
|
||||
// time hint
|
||||
let timeDesc = "";
|
||||
const now = new Date();
|
||||
switch (currentSelect) {
|
||||
case "日":
|
||||
timeDesc = dayjs().subtract(1, 'day').format('YYYY.MM.DD') + " 7点 - " + dayjs().format('YYYY.MM.DD') + " 7点";
|
||||
break;
|
||||
case "周":
|
||||
timeDesc = dayjs().subtract(7, 'day').format('YYYY.MM.DD') + " - " + dayjs().subtract(1, 'day').format('YYYY.MM.DD') ;
|
||||
break;
|
||||
case "月":
|
||||
timeDesc = dayjs().subtract(1, 'month').format('YYYY.MM.') + "29 - " + dayjs().format('YYYY.MM.') + '28' ;
|
||||
break;
|
||||
case "年":
|
||||
timeDesc = dayjs().subtract(1, 'year').endOf('year').format('YYYY.MM.') + "29 - " + dayjs().endOf('year').format('YYYY.MM.') + '28' ;
|
||||
break;
|
||||
}
|
||||
return (
|
||||
<GraphBase
|
||||
icon="chart"
|
||||
title="产线缺陷统计"
|
||||
dateOptions={["日", "周", "月", "年"]}
|
||||
defaultSelect={currentSelect}
|
||||
onDateChange={handleDateChange}
|
||||
size={bgSize}
|
||||
desc={timeDesc}
|
||||
style={{ width: "600px" }}
|
||||
>
|
||||
<div className={cls.chart}>
|
||||
{currentStatistic.length != 0 && (
|
||||
<ReactECharts option={options} style={{ height: "100%" }} />
|
||||
)}
|
||||
{currentStatistic.length == 0 && (
|
||||
<p
|
||||
style={{
|
||||
paddingTop: "72px",
|
||||
color: "#fff6",
|
||||
textAlign: "center",
|
||||
fontSize: "24px",
|
||||
}}
|
||||
>
|
||||
暂无数据
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
</GraphBase>
|
||||
);
|
||||
return (
|
||||
<GraphBase
|
||||
icon="battery"
|
||||
title="产线当日缺陷分类"
|
||||
dateOptions={['日', '周', '月', '年']}
|
||||
onDateChange={handleDateChange}
|
||||
size={bgSize}
|
||||
style={{ width: '600px' }}
|
||||
>
|
||||
<div className={cls.chart}>
|
||||
<ReactECharts option={options} style={{ height: '100%' }} />
|
||||
</div>
|
||||
</GraphBase>
|
||||
);
|
||||
}
|
||||
|
||||
export default FaultTotal;
|
||||
|
||||
function preHandleStatisticData(data, legend) {
|
||||
const obj = {};
|
||||
if (!data || !Array.isArray(data)) data = [];
|
||||
data.forEach((item) => {
|
||||
obj[item.name] = {};
|
||||
item.data.forEach((d) => {
|
||||
obj[item.name][d.checkType] = d.checkNum;
|
||||
});
|
||||
});
|
||||
|
||||
const series = Array(legend.length)
|
||||
.fill(1)
|
||||
.map((_) => ({
|
||||
name: "",
|
||||
type: "bar",
|
||||
stack: "true",
|
||||
barWidth: 12,
|
||||
emphasis: {
|
||||
focus: "series",
|
||||
},
|
||||
data: [],
|
||||
}));
|
||||
|
||||
legend.forEach((item, index) => {
|
||||
series[index].name = item;
|
||||
data.forEach((d, idx) => {
|
||||
if (index == legend.length - 1) {
|
||||
series[index].label = {
|
||||
show: true,
|
||||
position: "top",
|
||||
distance: 10,
|
||||
color: "#fffc",
|
||||
formatter: (params) => data[params.dataIndex].sum,
|
||||
};
|
||||
}
|
||||
// const sum = d.sum;
|
||||
// console.log("d", d, sum);
|
||||
// series[index].label = ((fff) => {
|
||||
// console.log("===>", fff);
|
||||
// return {
|
||||
// show: true,
|
||||
// position: "top",
|
||||
// distance: 10,
|
||||
// color: "#fffc",
|
||||
// formatter: "asdf" + fff,
|
||||
// };
|
||||
// })(sum);
|
||||
|
||||
series[index].data.push(obj[d.name][item] || 0);
|
||||
});
|
||||
});
|
||||
|
||||
return series;
|
||||
}
|
||||
|
||||
function getOptions(series, isra, currentStatistic) {
|
||||
return {
|
||||
color: ["#2760FF", "#8167F6", "#5B9BFF", "#99D66C", "#FFD160", "#FF8A40"],
|
||||
grid: {
|
||||
top: (isra.checkType || []).length <= 10 ? 80 : 100,
|
||||
right: 12,
|
||||
bottom: 20,
|
||||
left: 48,
|
||||
},
|
||||
legend: {
|
||||
top: 10,
|
||||
left: 60,
|
||||
padding: 5,
|
||||
itemWidth: 12,
|
||||
itemHeight: 12,
|
||||
itemGap: 12,
|
||||
height: 12,
|
||||
textStyle: {
|
||||
color: "#DFF1FE",
|
||||
fontSize: 12,
|
||||
},
|
||||
data: isra.checkType,
|
||||
},
|
||||
xAxis: {
|
||||
type: "category",
|
||||
data: currentStatistic.map((item) => item.name),
|
||||
axisLabel: {
|
||||
color: "#fffc",
|
||||
fontSize: 12,
|
||||
},
|
||||
axisTick: { show: false },
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
width: 1,
|
||||
color: "#213259",
|
||||
},
|
||||
},
|
||||
},
|
||||
yAxis: {
|
||||
name: "单位/个",
|
||||
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",
|
||||
},
|
||||
},
|
||||
},
|
||||
series,
|
||||
tooltip: {
|
||||
trigger: "axis",
|
||||
axisPointer: {
|
||||
type: "shadow",
|
||||
},
|
||||
className: "xc-chart-tooltip",
|
||||
// backgroundColor: ''
|
||||
},
|
||||
};
|
||||
}
|
||||
|
@ -1,244 +1,107 @@
|
||||
import cls from "./index.module.css";
|
||||
import GraphBase from "../GraphBase";
|
||||
import ReactECharts from "echarts-for-react";
|
||||
import { useSelector } from "react-redux";
|
||||
import { useEffect, useState } from "react";
|
||||
import { randomInt } from "../../../utils";
|
||||
import * as echarts from "echarts";
|
||||
import cls from './index.module.css';
|
||||
import GraphBase from '../GraphBase';
|
||||
import ReactECharts from 'echarts-for-react';
|
||||
import { useState } from 'react';
|
||||
|
||||
function FaultType(props) {
|
||||
const [init, setInit] = useState(true);
|
||||
const [currentLine, setCurrentLine] = useState("Y61");
|
||||
const isra = useSelector((state) => state.isra);
|
||||
const currentStatistic = isra.dayStatistic || [];
|
||||
const currentLineStatistic =
|
||||
currentLine != ""
|
||||
? currentStatistic.find((item) => item.name === currentLine)?.data || []
|
||||
: [];
|
||||
const lines = currentStatistic.map((item) => item.name);
|
||||
const CHART_TYPE = "line"; // "pie" | "line";
|
||||
const options = {
|
||||
colors: [
|
||||
'#2760FF',
|
||||
'#5B9BFF',
|
||||
'#FFD160',
|
||||
'#8167F6',
|
||||
'#99D66C',
|
||||
'#FF8A40',
|
||||
'#12FFF5',
|
||||
],
|
||||
grid: {
|
||||
left: 24,
|
||||
top: 10,
|
||||
bottom: 10,
|
||||
right: 24,
|
||||
},
|
||||
legend: {
|
||||
icon: 'circle',
|
||||
top: 32,
|
||||
right: 0,
|
||||
bottom: 32,
|
||||
width: 296,
|
||||
height: 130,
|
||||
itemGap: 30,
|
||||
formatter: function (name) {
|
||||
return `${name} {sub|${
|
||||
options.series[0].data.find((o) => o.name == name).value
|
||||
}}`;
|
||||
},
|
||||
textStyle: {
|
||||
color: '#DFF1FE',
|
||||
fontSize: 18,
|
||||
rich: {
|
||||
sub: {
|
||||
color: '#fff9',
|
||||
fontSize: 18,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
series: [
|
||||
{
|
||||
type: 'pie',
|
||||
center: ['26%', '54%'],
|
||||
radius: ['55%', '75%'],
|
||||
avoidLabelOverlap: false,
|
||||
label: {
|
||||
show: true,
|
||||
formatter: '{d}%',
|
||||
fontSize: 14,
|
||||
color: 'inherit',
|
||||
},
|
||||
labelLine: {
|
||||
length: 0,
|
||||
},
|
||||
data: [
|
||||
{ value: 1048, name: '缺陷1' },
|
||||
{ value: 735, name: '缺陷2' },
|
||||
{ value: 580, name: '缺陷3' },
|
||||
{ value: 484, name: '缺陷4' },
|
||||
{ value: 300, name: '缺陷5' },
|
||||
{ value: 300, name: '缺陷6' },
|
||||
{ value: 300, name: '缺陷8' },
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (init == false) return;
|
||||
if (lines.length) {
|
||||
setInit(false);
|
||||
setCurrentLine(lines[0]);
|
||||
}
|
||||
}, [lines]);
|
||||
const [lines, setLines] = useState([
|
||||
{ id: 1, label: '产线1', value: 'l1' },
|
||||
{ id: 2, label: '产线2', value: 'l2' },
|
||||
{ id: 3, label: '产线3', value: 'l3' },
|
||||
{ id: 4, label: '产线4', value: 'l4' },
|
||||
{ id: 5, label: '产线5', value: 'l5' },
|
||||
]);
|
||||
|
||||
const options = init
|
||||
? {}
|
||||
: getOptions(
|
||||
CHART_TYPE == "pie"
|
||||
? getSeries(currentStatistic, currentLine)
|
||||
: currentLineStatistic,
|
||||
CHART_TYPE
|
||||
);
|
||||
function handleDateChange(v) {
|
||||
console.log('date ', v);
|
||||
}
|
||||
|
||||
function handleLineChange(line) {
|
||||
setCurrentLine(line);
|
||||
}
|
||||
// 根据使用的页面决定背景的大小
|
||||
const bgSize =
|
||||
props.page == 'home' ? ['middle', 'short'] : ['middle', 'short'];
|
||||
|
||||
// 根据使用的页面决定背景的大小
|
||||
const bgSize =
|
||||
props.page == "home" ? ["middle", "short"] : ["middle", "short"];
|
||||
|
||||
return (
|
||||
<GraphBase
|
||||
icon="default"
|
||||
title="产线当日缺陷分类"
|
||||
dateOptions={[...lines]}
|
||||
defaultSelect={currentLine}
|
||||
onDateChange={handleLineChange}
|
||||
size={bgSize}
|
||||
selectWidth={64}
|
||||
style={{ width: "600px" }}
|
||||
>
|
||||
<div className={cls.chart}>
|
||||
{currentStatistic.length == 0 && (
|
||||
<p
|
||||
style={{
|
||||
paddingTop: "72px",
|
||||
color: "#fff6",
|
||||
textAlign: "center",
|
||||
fontSize: "24px",
|
||||
}}
|
||||
>
|
||||
暂无数据
|
||||
</p>
|
||||
)}
|
||||
{currentStatistic.length != 0 && (
|
||||
<ReactECharts option={options} style={{ height: "100%" }} />
|
||||
)}
|
||||
</div>
|
||||
</GraphBase>
|
||||
);
|
||||
return (
|
||||
<GraphBase
|
||||
icon="battery"
|
||||
title="产线当日缺陷分类"
|
||||
dateOptions={lines.map((item) => item.label)}
|
||||
onDateChange={handleDateChange}
|
||||
size={bgSize}
|
||||
style={{ width: '600px' }}
|
||||
>
|
||||
<div className={cls.chart}>
|
||||
<ReactECharts option={options} style={{ height: '100%' }} />
|
||||
</div>
|
||||
</GraphBase>
|
||||
);
|
||||
}
|
||||
|
||||
export default FaultType;
|
||||
|
||||
function getOptions(data, chart_type) {
|
||||
const color = [
|
||||
"#2760FF",
|
||||
"#8167F6",
|
||||
"#5B9BFF",
|
||||
"#99D66C",
|
||||
"#FFD160",
|
||||
"#FF8A40",
|
||||
];
|
||||
const grid = {
|
||||
left: 24,
|
||||
top: 10,
|
||||
bottom: 10,
|
||||
right: 24,
|
||||
};
|
||||
const legend_common = {
|
||||
icon: "circle",
|
||||
top: 32,
|
||||
right: 0,
|
||||
bottom: 32,
|
||||
width: 296,
|
||||
height: 130,
|
||||
itemGap: 30,
|
||||
textStyle: {
|
||||
color: "#DFF1FE",
|
||||
fontSize: 18,
|
||||
rich: {
|
||||
sub: {
|
||||
color: "#fff9",
|
||||
fontSize: 18,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
if (chart_type == "pie") {
|
||||
return {
|
||||
color,
|
||||
grid,
|
||||
legend: {
|
||||
...legend_common,
|
||||
formatter: function (name) {
|
||||
return `${name} {sub|${
|
||||
data[0].data.find((o) => o.name == name).value
|
||||
}}`;
|
||||
},
|
||||
},
|
||||
series: data,
|
||||
};
|
||||
} else if (chart_type == "line") {
|
||||
const dataList = data.map((item) => ({
|
||||
category: item.checkType,
|
||||
value: item.checkNum,
|
||||
}));
|
||||
|
||||
return {
|
||||
grid: {
|
||||
top: 48,
|
||||
left: 48,
|
||||
bottom: 40,
|
||||
right: 18,
|
||||
},
|
||||
legend: {
|
||||
...legend_common,
|
||||
},
|
||||
tooltip: {
|
||||
trigger: "axis",
|
||||
axisPointer: {
|
||||
type: "shadow",
|
||||
},
|
||||
symbol: 'rect',
|
||||
className: "xc-chart-tooltip",
|
||||
// backgroundColor: ''
|
||||
},
|
||||
xAxis: {
|
||||
type: "category",
|
||||
data: (dataList || []).map((item) => item.category),
|
||||
axisLabel: {
|
||||
color: "#fff",
|
||||
fontSize: 10,
|
||||
rotate: 20,
|
||||
},
|
||||
axisTick: { show: false },
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
width: 1,
|
||||
color: "#213259",
|
||||
},
|
||||
},
|
||||
},
|
||||
yAxis: {
|
||||
name: "单位/个",
|
||||
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",
|
||||
},
|
||||
},
|
||||
},
|
||||
series: [
|
||||
{
|
||||
type: "bar",
|
||||
barWidth: 14,
|
||||
itemStyle: {
|
||||
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
||||
// i % 8 避免超过8个数据时无颜色的问题
|
||||
{ offset: 0, color: "#5CB7FF" },
|
||||
{ offset: 1, color: "#364BFE" },
|
||||
]),
|
||||
},
|
||||
label: {
|
||||
show: true,
|
||||
position: "top",
|
||||
distance: 10,
|
||||
fontSize: 10,
|
||||
color: "#fffc",
|
||||
},
|
||||
data: (dataList || []).map((item) =>
|
||||
item.value == null || isNaN(+item.value) ? null : (+item.value).toFixed(0)
|
||||
),
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
function getSeries(currentStatistic, currentLine) {
|
||||
const currentItem = currentStatistic.find((item) => item.name == currentLine);
|
||||
return [
|
||||
{
|
||||
type: "pie",
|
||||
center: ["26%", "54%"],
|
||||
radius: ["55%", "75%"],
|
||||
avoidLabelOverlap: false,
|
||||
label: {
|
||||
show: true,
|
||||
formatter: "{d}%",
|
||||
fontSize: 14,
|
||||
color: "inherit",
|
||||
},
|
||||
labelLine: {
|
||||
length: 0,
|
||||
},
|
||||
data: currentItem.data.map((item) => ({
|
||||
value: item.checkNum,
|
||||
name: item.checkType,
|
||||
})),
|
||||
},
|
||||
];
|
||||
}
|
||||
|
@ -1,19 +1,19 @@
|
||||
import cls from "./good.module.scss";
|
||||
import Container from "../../Container";
|
||||
import TodayTableData from "./components/TodayTableData";
|
||||
import GoodRateChart from "./components/GoodRateChart";
|
||||
import TechSplitline from "../TechSplitline";
|
||||
import cls from './good.module.scss';
|
||||
import Container from '../../Container';
|
||||
import TodayTableData from './components/TodayTableData';
|
||||
import GoodRateChart from './components/GoodRateChart';
|
||||
import TechSplitline from '../TechSplitline';
|
||||
|
||||
const GoodProduction = () => {
|
||||
return (
|
||||
<Container icon="good" title="本日生产良品率" className={cls.goodProd}>
|
||||
<div className={`${cls.goodProd__content} h-full`}>
|
||||
<TodayTableData />
|
||||
<TechSplitline />
|
||||
<GoodRateChart />
|
||||
</div>
|
||||
</Container>
|
||||
);
|
||||
return (
|
||||
<Container icon="good" title="本日生产良品率" className={cls.goodProd}>
|
||||
<div className={`${cls.goodProd__content} h-full`}>
|
||||
<TodayTableData />
|
||||
<TechSplitline />
|
||||
<GoodRateChart />
|
||||
</div>
|
||||
</Container>
|
||||
);
|
||||
};
|
||||
|
||||
export default GoodProduction;
|
||||
|
@ -1,313 +1,155 @@
|
||||
import cls from "./index.module.css";
|
||||
import "./overwrite.css"; // 覆写 antd 默认样式,全局
|
||||
import ReactECharts from "echarts-for-react";
|
||||
import * as echarts from "echarts";
|
||||
import { Switch, Select, Radio } from "antd";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useSelector } from "react-redux";
|
||||
import triangle from "../../../../../assets/Icon/triangle.svg";
|
||||
import dayjs from "dayjs";
|
||||
|
||||
const dateOptions = { day: "日", week: "周", month: "月", year: "年" };
|
||||
import cls from './index.module.css';
|
||||
import './overwrite.css'; // 覆写 antd 默认样式,全局
|
||||
import ReactECharts from 'echarts-for-react';
|
||||
import * as echarts from 'echarts';
|
||||
import { Switch, Radio } from 'antd';
|
||||
import { randomInt } from '../../../../../utils';
|
||||
|
||||
const GoodRateChart = (props) => {
|
||||
// 是否展示班次数据
|
||||
const [showMore, setShowMore] = useState(false);
|
||||
// 更新 key,用于刷新图表
|
||||
const [updateKey, setUpdateKey] = useState(Date.now());
|
||||
// 默认的日期类型
|
||||
const [dateType, setDateType] = useState("day");
|
||||
const [defaultSelect, setDefaultSelect] = useState(dateOptions[dateType]);
|
||||
const cutting = useSelector((state) => state.cutting);
|
||||
useEffect(() => {
|
||||
setUpdateKey(Date.now());
|
||||
}, [showMore]);
|
||||
const options = {
|
||||
color: ['#FFD160', '#12FFF5', '#2760FF'],
|
||||
grid: { top: 28, right: 12, bottom: 32, 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: {
|
||||
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) {
|
||||
// val: boolean
|
||||
setShowMore(val);
|
||||
}
|
||||
function handleSwitchChange(val) {
|
||||
// val: boolean
|
||||
console.log('switch change', val);
|
||||
}
|
||||
|
||||
const [timestr, setTimestr] = useState(
|
||||
dayjs().subtract(1, "day").format("YYYY.MM.DD") +
|
||||
" 7点 - " +
|
||||
dayjs().format("YYYY.MM.DD") +
|
||||
" 7点"
|
||||
);
|
||||
function handleDateChange(value) {
|
||||
// e: Event
|
||||
let v = "day";
|
||||
switch (value) {
|
||||
case "日":
|
||||
setTimestr(
|
||||
dayjs().subtract(1, "day").format("YYYY.MM.DD") +
|
||||
" 7点 - " +
|
||||
dayjs().format("YYYY.MM.DD") +
|
||||
" 7点"
|
||||
);
|
||||
break;
|
||||
case "月":
|
||||
v = "month";
|
||||
setTimestr(
|
||||
dayjs().subtract(1, "month").format("YYYY.MM.") +
|
||||
"29 - " +
|
||||
dayjs().format("YYYY.MM.") +
|
||||
"28"
|
||||
);
|
||||
break;
|
||||
case "周":
|
||||
v = "week";
|
||||
setTimestr(
|
||||
dayjs().subtract(7, "day").format("YYYY.MM.DD") +
|
||||
" - " +
|
||||
dayjs().subtract(1, "day").format("YYYY.MM.DD")
|
||||
);
|
||||
break;
|
||||
case "年":
|
||||
v = "year";
|
||||
setTimestr(
|
||||
dayjs().subtract(1, "year").endOf("year").format("YYYY.MM.") +
|
||||
"29 - " +
|
||||
dayjs().endOf("year").format("YYYY.MM.") +
|
||||
"28"
|
||||
);
|
||||
break;
|
||||
}
|
||||
setDateType(v);
|
||||
}
|
||||
|
||||
// 根据日期类型,数据列表,是否展示班次数据,生成对应的 options
|
||||
const options = getOptions(cutting.chart[dateType], showMore, dateType);
|
||||
|
||||
return (
|
||||
<div className={cls.GoodRateChart}>
|
||||
<div className={cls.titleBar}>
|
||||
<h2>生产良品率</h2>
|
||||
<Switch defaultChecked={showMore} onChange={handleSwitchChange} />
|
||||
<div className={cls.legend}>
|
||||
<span className="legend__title">班次详情</span>
|
||||
<ul className="legend__list">
|
||||
<li>总量</li>
|
||||
{showMore && (
|
||||
<>
|
||||
<li>白班</li>
|
||||
<li>夜班</li>
|
||||
</>
|
||||
)}
|
||||
</ul>
|
||||
</div>
|
||||
<div className={cls.graphBaseDesc}>{timestr}</div>
|
||||
<Select
|
||||
defaultValue={defaultSelect}
|
||||
style={{ width: 60 }}
|
||||
popupClassName="xc-date-selector-menu"
|
||||
className={cls.radioGroup}
|
||||
options={["日", "周", "月", "年"].map((item) => ({
|
||||
label: item,
|
||||
value: item,
|
||||
}))}
|
||||
suffixIcon={<img src={triangle} alt="#" />}
|
||||
notFoundContent={
|
||||
<span
|
||||
style={{
|
||||
color: "#fff",
|
||||
fontSize: "14px",
|
||||
lineHeight: 1,
|
||||
paddingLeft: "12px",
|
||||
}}
|
||||
>
|
||||
- 无 -
|
||||
</span>
|
||||
}
|
||||
onChange={(value, option) => handleDateChange(value)}
|
||||
/>
|
||||
{/* <Radio.Group
|
||||
defaultValue="day"
|
||||
buttonStyle="solid"
|
||||
onChange={handleDateChange}
|
||||
className={cls.radioGroup}
|
||||
style={{ flex: 1, textAlign: "right" }}
|
||||
>
|
||||
<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>
|
||||
{options && <ReactECharts key={updateKey} option={options} />}
|
||||
{!options && (
|
||||
<p
|
||||
style={{
|
||||
paddingTop: "88px",
|
||||
color: "#fffc",
|
||||
textAlign: "center",
|
||||
fontSize: "24px",
|
||||
userSelect: "none",
|
||||
}}
|
||||
>
|
||||
暂无数据
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
return (
|
||||
<div className={cls.GoodRateChart}>
|
||||
<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>
|
||||
<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} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default GoodRateChart;
|
||||
|
||||
function getOptions(dataList, showMore, dateType) {
|
||||
const list = [...dataList].sort((a, b) => a.dataTime - b.dataTime);
|
||||
|
||||
console.log(
|
||||
"list ",
|
||||
list.filter((item) => item.sum)
|
||||
);
|
||||
if (list.length === 0 || list.filter((item) => item.sum).length == 0)
|
||||
return null;
|
||||
const color = ["#FFD160", "#12FFF5", "#2760FF"];
|
||||
const grid = { top: 28, right: 12, bottom: showMore ? 72 : 64, left: 48 };
|
||||
const xAxis = {
|
||||
type: "category",
|
||||
data: list.map((item) =>
|
||||
dateType == "day"
|
||||
? item.dataTime.split("T")[1]
|
||||
: item.dataTime.split("T")[0]
|
||||
),
|
||||
axisLabel: {
|
||||
color: "#fff",
|
||||
fontSize: 10,
|
||||
rotate: 25,
|
||||
margin: 13,
|
||||
},
|
||||
axisTick: { show: false },
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
width: 1,
|
||||
color: "#213259",
|
||||
},
|
||||
},
|
||||
};
|
||||
const yAxis = {
|
||||
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,
|
||||
};
|
||||
const seriesTeam = [
|
||||
{
|
||||
name: "白班",
|
||||
data: list.map((item) => (item.day * 100).toFixed(2)),
|
||||
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" },
|
||||
]),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "夜班",
|
||||
data: list.map((item) => (item.night * 100).toFixed(2)),
|
||||
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" },
|
||||
]),
|
||||
},
|
||||
},
|
||||
];
|
||||
return {
|
||||
grid,
|
||||
color,
|
||||
xAxis,
|
||||
yAxis,
|
||||
tooltip: {
|
||||
trigger: "axis",
|
||||
color: "#fff",
|
||||
formatter: showMore
|
||||
? "{a0} {c0}%<br />{a1} {c1}%<br />{a2} {c2}%"
|
||||
: "{b} {c}%",
|
||||
axisPointer: {
|
||||
type: "shadow",
|
||||
},
|
||||
textStyle: {
|
||||
color: "#fffc",
|
||||
},
|
||||
className: "xc-chart-tooltip",
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: "总量",
|
||||
data: list.map((item) =>
|
||||
item.sum != null ? (item.sum * 100).toFixed(2) : "-- "
|
||||
),
|
||||
type: "line",
|
||||
symbol: "circle",
|
||||
symbolSize: 6,
|
||||
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,
|
||||
},
|
||||
...(showMore ? seriesTeam : []),
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
// {
|
||||
// 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((_, index) => {
|
||||
// const today = new Date();
|
||||
// const dtimestamp = today - index * 24 * 60 * 60 * 1000;
|
||||
// return `${new Date(dtimestamp).getMonth() + 1}.${new Date(
|
||||
// dtimestamp
|
||||
// ).getDate()}`;
|
||||
// })
|
||||
// .reverse(),
|
||||
|
@ -1,95 +1,86 @@
|
||||
.GoodRateChart {
|
||||
height: 1px;
|
||||
flex: 1;
|
||||
padding-top: 8px;
|
||||
/* background: #ae27276a; */
|
||||
height: 1px;
|
||||
flex: 1;
|
||||
padding-top: 8px;
|
||||
/* background: #ae27276a; */
|
||||
}
|
||||
.GoodRateChart .titleBar {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
gap: 5px;
|
||||
color: white;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
color: white;
|
||||
}
|
||||
.GoodRateChart .titleBar h2 {
|
||||
margin: 0;
|
||||
font-size: 16px;
|
||||
line-height: 32px;
|
||||
letter-spacing: 1px;
|
||||
color: #52fff8;
|
||||
margin: 0;
|
||||
font-size: 18px;
|
||||
line-height: 32px;
|
||||
letter-spacing: 1.2px;
|
||||
color: #52fff8;
|
||||
}
|
||||
|
||||
.GoodRateChart .titleBar .legend {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.GoodRateChart .titleBar .legend * {
|
||||
font-size: 14px;
|
||||
line-height: 14px;
|
||||
color: #dff1fe;
|
||||
}
|
||||
|
||||
.graphBaseDesc {
|
||||
margin: 0 6px;
|
||||
font-size: 16px;
|
||||
color: #76fff9;
|
||||
flex: 1;
|
||||
font-size: 14px;
|
||||
line-height: 14px;
|
||||
color: #dff1fe;
|
||||
}
|
||||
|
||||
.GoodRateChart .titleBar .legend ul {
|
||||
display: flex;
|
||||
margin: 0;
|
||||
margin-left: 5px;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
margin: 0;
|
||||
margin-left: 8px;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
align-items: center;
|
||||
}
|
||||
.GoodRateChart .titleBar .legend ul li {
|
||||
position: relative;
|
||||
margin: 4px;
|
||||
padding-left: 16px;
|
||||
position: relative;
|
||||
margin: 4px;
|
||||
padding-left: 16px;
|
||||
}
|
||||
.GoodRateChart .titleBar .legend ul li::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 2px;
|
||||
top: 2px;
|
||||
display: inline-block;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
border-radius: 2px;
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 2px;
|
||||
top: 2px;
|
||||
display: inline-block;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.GoodRateChart .titleBar .legend ul li:first-child::before {
|
||||
background-color: #ffd160;
|
||||
background-color: #ffd160;
|
||||
}
|
||||
|
||||
.GoodRateChart .titleBar .legend ul li:nth-child(2)::before {
|
||||
background-color: #12fff5;
|
||||
background-color: #12fff5;
|
||||
}
|
||||
|
||||
.GoodRateChart .titleBar .legend ul li:nth-child(3)::before {
|
||||
background-color: #2760ff;
|
||||
background-color: #2760ff;
|
||||
}
|
||||
|
||||
.radioGroup * {
|
||||
border: none !important;
|
||||
border-radius: 6px !important;
|
||||
/* transform: translateX(224px) !important; */
|
||||
border: none !important;
|
||||
border-radius: 0 !important;
|
||||
}
|
||||
.radioGroup *:focus-within {
|
||||
box-shadow: none !important;
|
||||
box-shadow: none !important;
|
||||
}
|
||||
|
||||
.radioGroup *::before {
|
||||
width: 0 !important;
|
||||
width: 0 !important;
|
||||
}
|
||||
|
||||
.radioGroup_button_wrapper {
|
||||
color: #fff !important;
|
||||
background: #03233c !important;
|
||||
color: #fff !important;
|
||||
background: #03233c !important;
|
||||
}
|
||||
|
||||
.radioGroup_button_wrapper.ant-radio-button-wrapper-checked {
|
||||
background: #02457e !important;
|
||||
background: #02457e !important;
|
||||
}
|
||||
|
@ -1,82 +1,34 @@
|
||||
import { useState } from "react";
|
||||
import cls from "./index.module.scss";
|
||||
import { ScrollBoard } from "@jiaminghi/data-view-react";
|
||||
import { useSelector } from "react-redux";
|
||||
|
||||
function getRate(decimal) {
|
||||
return decimal != null ? (decimal * 100).toFixed(2) + "%" : undefined;
|
||||
}
|
||||
|
||||
const TodayTableData = (props) => {
|
||||
const cutting = useSelector((state) => state.cutting);
|
||||
|
||||
// let cutting = {
|
||||
// table: [
|
||||
// {
|
||||
// lineName: "Y61",
|
||||
// first: 0.37,
|
||||
// second: 0.03,
|
||||
// product: 0.99,
|
||||
// waste: 0.01,
|
||||
// },
|
||||
// ],
|
||||
// chart: {},
|
||||
// };
|
||||
const config = {
|
||||
const [config, setConfig] = useState({
|
||||
// headerBGC: 'rgba(4, 44, 76, 0.3)',
|
||||
// headerBGC: "rgba(4, 44, 76, .8)",
|
||||
headerBGC: "#044A8460",
|
||||
headerBGC: "rgba(4, 44, 76, .8)",
|
||||
header: [
|
||||
'<span style="color:#fff; padding-left: 12px;">产线<span/>',
|
||||
'<span style="color:#fff; padding-left: 12px;">一等率<span/>',
|
||||
'<span style="color:#fff; padding-left: 12px;">二等率<span/>',
|
||||
'<span style="color:#fff; padding-left: 12px;">成品率<span/>',
|
||||
'<span style="color:#fff; padding-left: 12px;">废品率<span/>',
|
||||
'<span style="color:#fff">产线<span/>',
|
||||
'<span style="color:#fff">一等率<span/>',
|
||||
'<span style="color:#fff">二等率<span/>',
|
||||
'<span style="color:#fff">成品率<span/>',
|
||||
'<span style="color:#fff">废品率<span/>',
|
||||
],
|
||||
// oddRowBGC: "#042444",
|
||||
// evenRowBGC: "#042c4c",
|
||||
oddRowBGC: "#044A8460",
|
||||
evenRowBGC: "#0b549970",
|
||||
oddRowBGC: "#042444",
|
||||
evenRowBGC: "#042c4c",
|
||||
columnWidth: [90],
|
||||
headerHeight: 40,
|
||||
hoverPause: false,
|
||||
data: cutting.table.map((line) => [
|
||||
line.lineName,
|
||||
getRate(line.first),
|
||||
getRate(line.second),
|
||||
getRate(line.product),
|
||||
getRate(line.waste),
|
||||
]),
|
||||
// data: [
|
||||
// ["Y61", "37%", "62%", "97%", "7%"],
|
||||
// ["Y62", "95%", "10%", "99%", "3%"],
|
||||
// ["Y63", "68%", "1%", "92%", "4%"],
|
||||
// ["Y64", "94%", "21%", "97%", "2%"],
|
||||
// ["Y65", "99%", "30%", "95%", "5%"],
|
||||
// ],
|
||||
};
|
||||
data: [
|
||||
["产线1", "37%", "62%", "97%", "7%"],
|
||||
["产线2", "95%", "10%", "99%", "3%"],
|
||||
["产线3", "68%", "1%", "92%", "4%"],
|
||||
["产线4", "94%", "21%", "97%", "2%"],
|
||||
["产线5", "99%", "30%", "95%", "5%"],
|
||||
],
|
||||
});
|
||||
return (
|
||||
<div className={cls.todayTableData}>
|
||||
{config.data.length != 0 && (
|
||||
<ScrollBoard
|
||||
className={cls.paddingCeil}
|
||||
config={config}
|
||||
style={{ width: "100%", color: "#fffc" }}
|
||||
/>
|
||||
)}
|
||||
{config.data.length == 0 && (
|
||||
<p
|
||||
style={{
|
||||
color: "#cccf",
|
||||
fontSize: "24px",
|
||||
userSelect: "none",
|
||||
textAlign: "center",
|
||||
paddingTop: "48px",
|
||||
}}
|
||||
>
|
||||
暂无数据
|
||||
</p>
|
||||
)}
|
||||
<ScrollBoard config={config} style={{ width: "100%" }} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
@ -1,44 +1,23 @@
|
||||
import { useEffect, useRef } from "react";
|
||||
import useIcon from "../hooks/useIcon";
|
||||
import cls from "./container.module.scss";
|
||||
import { useEffect, useRef } from 'react';
|
||||
import useIcon from '../hooks/useIcon';
|
||||
import cls from './container.module.scss';
|
||||
|
||||
const Container = (props) => {
|
||||
let icon = useIcon(props.icon);
|
||||
let icon = useIcon(props.icon);
|
||||
|
||||
const desc = props.desc;
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`${cls.container} ${props.className}`}
|
||||
style={props.pending ? { filter: "grayscale(100%)" } : props.style}
|
||||
>
|
||||
<div className={cls.container__head}>
|
||||
<img
|
||||
src={icon}
|
||||
alt="#"
|
||||
className={props.icon == "kiln" ? cls.bigger : ""}
|
||||
/>
|
||||
<h2>{props.title}</h2>
|
||||
{desc && <div className={cls.graphBaseDesc}>{desc}</div>}
|
||||
</div>
|
||||
<div className={cls.container__content}>{props.children}</div>
|
||||
{props.pending && (
|
||||
<div
|
||||
className={`${cls.container__content} pending-modal`}
|
||||
style={{
|
||||
position: "absolute",
|
||||
top: 0,
|
||||
left: 0,
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
borderRadius: "20px",
|
||||
userSelect: "none",
|
||||
cursor: "not-allowed",
|
||||
}}
|
||||
></div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
return (
|
||||
<div className={`${cls.container} ${props.className}`} style={props.style}>
|
||||
<div className={cls.container__head}>
|
||||
<img
|
||||
src={icon}
|
||||
alt="#"
|
||||
className={props.icon == 'kiln' ? cls.bigger : ''}
|
||||
/>
|
||||
<h2>{props.title}</h2>
|
||||
</div>
|
||||
<div className={cls.container__content}>{props.children}</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Container;
|
||||
|
@ -1,222 +1,37 @@
|
||||
import GraphBase from "../../../Common/GraphBase";
|
||||
import ReactECharts from "echarts-for-react";
|
||||
// import getOptions from "../../../../hooks/getChartOption";
|
||||
import { useSelector } from "react-redux";
|
||||
import { useState } from "react";
|
||||
import * as echarts from "echarts";
|
||||
import { lunarYear } from "../../../../utils/energeChartOption";
|
||||
import dayjs from "dayjs";
|
||||
import GraphBase from '../../../Common/GraphBase';
|
||||
import ReactECharts from 'echarts-for-react';
|
||||
import getOptions from '../../../../hooks/getChartOption';
|
||||
|
||||
function Gas(props) {
|
||||
const elecTrend = useSelector((state) => state.energy.trend.natGas2);
|
||||
const [period, setPeriod] = useState("周");
|
||||
const [timestr, setTimestr] = useState(
|
||||
dayjs().subtract(7, "day").format("YYYY.MM.DD") +
|
||||
" - " +
|
||||
dayjs().subtract(1, "day").format("YYYY.MM.DD")
|
||||
);
|
||||
const options = getOptions(
|
||||
{ 周: "week", 月: "month", 年: "year" }[period],
|
||||
elecTrend ?? { week: [], month: [], year: [] }
|
||||
);
|
||||
function handleSwitch(v) {
|
||||
console.log('switched ', v);
|
||||
}
|
||||
|
||||
function handleSwitch(v) {
|
||||
// console.log('switched ', v);
|
||||
}
|
||||
function handleDateChange(v) {
|
||||
console.log('date ', v);
|
||||
}
|
||||
|
||||
|
||||
function handleDateChange(value) {
|
||||
setPeriod(value);
|
||||
setTimestr(
|
||||
{
|
||||
年:
|
||||
dayjs().subtract(1, "year").endOf("year").format("YYYY.MM.") +
|
||||
"29 - " +
|
||||
dayjs().endOf("year").format("YYYY.MM.") +
|
||||
"28",
|
||||
周:
|
||||
dayjs().subtract(7, "day").format("YYYY.MM.DD") +
|
||||
" - " +
|
||||
dayjs().subtract(1, "day").format("YYYY.MM.DD"),
|
||||
月:
|
||||
dayjs().subtract(1, "month").format("YYYY.MM.") +
|
||||
"29 - " +
|
||||
dayjs().format("YYYY.MM.") +
|
||||
"28",
|
||||
}[value]
|
||||
);
|
||||
}
|
||||
return (
|
||||
<GraphBase
|
||||
icon="battery"
|
||||
title="天然气II"
|
||||
desc={`能耗趋势图 ${timestr}`}
|
||||
switchOptions={false}
|
||||
onSwitch={handleSwitch}
|
||||
defaultSelect={period}
|
||||
dateOptions={["周", "月", "年"]}
|
||||
// legend={["总量"]}
|
||||
onDateChange={handleDateChange}
|
||||
size={["long", "middle"]}
|
||||
>
|
||||
{/* real echarts here */}
|
||||
{options && (
|
||||
<ReactECharts
|
||||
key={Math.random()}
|
||||
option={options}
|
||||
// option={getOptions([[21, 4, 74, 72, 9, 59, 63]], "氧气")}
|
||||
style={{ height: "100%" }}
|
||||
/>
|
||||
)}
|
||||
{!options && (
|
||||
<p
|
||||
style={{
|
||||
color: "#cccf",
|
||||
fontSize: "24px",
|
||||
userSelect: "none",
|
||||
textAlign: "center",
|
||||
paddingTop: "88px",
|
||||
}}
|
||||
>
|
||||
暂无数据
|
||||
</p>
|
||||
)}
|
||||
{/* real table data here */}
|
||||
</GraphBase>
|
||||
);
|
||||
return (
|
||||
<GraphBase
|
||||
icon="battery"
|
||||
title="焦炉煤气"
|
||||
desc="能耗趋势图"
|
||||
switchOptions={true}
|
||||
onSwitch={handleSwitch}
|
||||
dateOptions={['日', '周', '月', '年']}
|
||||
legend={['总量']}
|
||||
onDateChange={handleDateChange}
|
||||
size={['long', 'short']}
|
||||
>
|
||||
{/* real echarts here */}
|
||||
<ReactECharts
|
||||
key={Math.random()}
|
||||
option={getOptions([[21, 4, 74, 72, 9, 59, 63]], '氧气')}
|
||||
style={{ height: '100%' }}
|
||||
/>
|
||||
{/* real table data here */}
|
||||
</GraphBase>
|
||||
);
|
||||
}
|
||||
|
||||
export default Gas;
|
||||
|
||||
function getOptions(period, trend) {
|
||||
if (trend[period].length === 0) return null;
|
||||
// export default function getOptions(seriesData, name) {
|
||||
const today = new Date();
|
||||
const currentYear = today.getFullYear();
|
||||
const currentMonth = today.getMonth() + 1;
|
||||
let days = 30;
|
||||
if (period == "month") {
|
||||
if (currentMonth in [1, 3, 5, 7, 8, 10, 12]) {
|
||||
days = 31;
|
||||
} else if (currentMonth == 2) {
|
||||
days = lunarYear(currentYear) ? 29 : 28;
|
||||
}
|
||||
}
|
||||
|
||||
const colors = [
|
||||
"#FFD160",
|
||||
"#12FFF5",
|
||||
"#2760FF",
|
||||
"#E80091",
|
||||
"#8064ff",
|
||||
"#ff8a3b",
|
||||
"#8cd26d",
|
||||
"#2aa1ff",
|
||||
];
|
||||
return {
|
||||
color: colors,
|
||||
grid: { top: 40, right: 12, bottom: 20, left: 80 },
|
||||
legend: {
|
||||
show: false,
|
||||
icon: "roundRect",
|
||||
top: 10,
|
||||
right: 10,
|
||||
padding: 0,
|
||||
itemWidth: 8,
|
||||
itemHeight: 8,
|
||||
itemGap: 3,
|
||||
height: 8,
|
||||
textStyle: {
|
||||
color: "#DFF1FE",
|
||||
fontSize: 12,
|
||||
},
|
||||
},
|
||||
xAxis: {
|
||||
type: "category",
|
||||
data: Array(period == "week" ? 7 : period == "year" ? 12 : days)
|
||||
.fill(1)
|
||||
.map((_, index) => {
|
||||
if (period == "week") {
|
||||
const dtimestamp = today - (index + 1) * 24 * 60 * 60 * 1000;
|
||||
return `${new Date(dtimestamp).getMonth() + 1}.${new Date(
|
||||
dtimestamp
|
||||
).getDate()}`;
|
||||
} else if (period == "month") {
|
||||
return `${currentMonth}.${days - index}`;
|
||||
} else {
|
||||
return `${currentYear}.${12 - index}`;
|
||||
}
|
||||
})
|
||||
.reverse(),
|
||||
axisLabel: {
|
||||
color: "#fff",
|
||||
fontSize: 14,
|
||||
},
|
||||
axisTick: { show: false },
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
width: 1,
|
||||
color: "#213259",
|
||||
},
|
||||
},
|
||||
},
|
||||
yAxis: {
|
||||
name: "单位/Nm³",
|
||||
nameTextStyle: {
|
||||
color: "#fff",
|
||||
fontSize: 16,
|
||||
align: "right",
|
||||
},
|
||||
type: "value",
|
||||
axisLabel: {
|
||||
color: "#fff",
|
||||
fontSize: 14,
|
||||
formatter: "{value}",
|
||||
},
|
||||
axisLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
color: "#213259",
|
||||
},
|
||||
},
|
||||
splitLine: {
|
||||
lineStyle: {
|
||||
color: "#213259a0",
|
||||
},
|
||||
},
|
||||
},
|
||||
series: {
|
||||
data: trend[period].map(item => item != null ? (+item).toFixed(2) : null),
|
||||
type: "line",
|
||||
symbol: "circle",
|
||||
symbolSize: 6,
|
||||
areaStyle: {
|
||||
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
||||
{ offset: 0, color: colors[0] + "40" },
|
||||
{ offset: 0.5, color: colors[0] + "20" },
|
||||
{ offset: 1, color: colors[0] + "00" },
|
||||
]),
|
||||
},
|
||||
},
|
||||
// series: seriesData.map((arr, index) => ({
|
||||
// name: index + 1 + '#' + name,
|
||||
// data: arr,
|
||||
// type: 'line',
|
||||
// areaStyle: {
|
||||
// color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
||||
// { offset: 0, color: colors[index] + '40' },
|
||||
// { offset: 0.5, color: colors[index] + '20' },
|
||||
// { offset: 1, color: colors[index] + '00' },
|
||||
// ]),
|
||||
// },
|
||||
// })),
|
||||
tooltip: {
|
||||
trigger: "axis",
|
||||
axisPointer: {
|
||||
type: "shadow",
|
||||
},
|
||||
className: "xc-chart-tooltip",
|
||||
// backgroundColor: ''
|
||||
},
|
||||
};
|
||||
}
|
||||
|
@ -1,204 +1,37 @@
|
||||
import GraphBase from "../../../Common/GraphBase";
|
||||
import ReactECharts from "echarts-for-react";
|
||||
import { useSelector } from "react-redux";
|
||||
import { useState } from "react";
|
||||
import * as echarts from "echarts";
|
||||
import dayjs from "dayjs";
|
||||
import GraphBase from '../../../Common/GraphBase';
|
||||
import ReactECharts from 'echarts-for-react';
|
||||
import getOptions from '../../../../hooks/getChartOption';
|
||||
|
||||
function ElecCost(props) {
|
||||
const elecTrend = useSelector((state) => state.energy.trend.elec);
|
||||
const [period, setPeriod] = useState("周");
|
||||
const [timestr, setTimestr] = useState(
|
||||
dayjs().subtract(7, "day").format("YYYY.MM.DD") +
|
||||
" - " +
|
||||
dayjs().subtract(1, "day").format("YYYY.MM.DD")
|
||||
);
|
||||
const options = getOptions(
|
||||
{ 周: "week", 月: "month", 年: "year" }[period],
|
||||
elecTrend ?? { week: [], month: [], year: [] }
|
||||
);
|
||||
function handleSwitch(v) {
|
||||
console.log('switched ', v);
|
||||
}
|
||||
|
||||
function handleSwitch(v) {
|
||||
// console.log('switched ', v);
|
||||
}
|
||||
function handleDateChange(v) {
|
||||
console.log('date ', v);
|
||||
}
|
||||
|
||||
function handleDateChange(value) {
|
||||
setPeriod(value);
|
||||
setTimestr(
|
||||
{
|
||||
年:
|
||||
dayjs().subtract(1, "year").endOf("year").format("YYYY.MM.") +
|
||||
"29 - " +
|
||||
dayjs().endOf("year").format("YYYY.MM.") +
|
||||
"28",
|
||||
周:
|
||||
dayjs().subtract(7, "day").format("YYYY.MM.DD") +
|
||||
" - " +
|
||||
dayjs().subtract(1, "day").format("YYYY.MM.DD"),
|
||||
月:
|
||||
dayjs().subtract(1, "month").format("YYYY.MM.") +
|
||||
"29 - " +
|
||||
dayjs().format("YYYY.MM.") +
|
||||
"28",
|
||||
}[value]
|
||||
);
|
||||
}
|
||||
return (
|
||||
<GraphBase
|
||||
icon="battery"
|
||||
title="电耗能"
|
||||
desc={`能耗趋势图 ${timestr}`}
|
||||
switchOptions={false}
|
||||
onSwitch={handleSwitch}
|
||||
defaultSelect={period}
|
||||
dateOptions={["周", "月", "年"]}
|
||||
// legend={["总量"]}
|
||||
onDateChange={handleDateChange}
|
||||
size={["long", "middle"]}
|
||||
>
|
||||
{/* real echarts here */}
|
||||
{options && (
|
||||
<ReactECharts
|
||||
key={Math.random()}
|
||||
option={options}
|
||||
// option={getOptions([[112, 73, 79, 82, 30, 105, 87]], "氧气")}
|
||||
style={{ height: "100%" }}
|
||||
/>
|
||||
)}
|
||||
{!options && (
|
||||
<p
|
||||
style={{
|
||||
color: "#cccf",
|
||||
fontSize: "24px",
|
||||
userSelect: "none",
|
||||
textAlign: "center",
|
||||
paddingTop: "48px",
|
||||
}}
|
||||
>
|
||||
暂无数据
|
||||
</p>
|
||||
)}
|
||||
{/* real table data here */}
|
||||
</GraphBase>
|
||||
);
|
||||
return (
|
||||
<GraphBase
|
||||
icon="battery"
|
||||
title="电耗能"
|
||||
desc="能耗趋势图"
|
||||
switchOptions={true}
|
||||
onSwitch={handleSwitch}
|
||||
dateOptions={['日', '周', '月', '年']}
|
||||
legend={['总量']}
|
||||
onDateChange={handleDateChange}
|
||||
size={['long', 'short']}
|
||||
>
|
||||
{/* real echarts here */}
|
||||
<ReactECharts
|
||||
key={Math.random()}
|
||||
option={getOptions([[112, 73, 79, 82, 30, 105, 87]], '氧气')}
|
||||
style={{ height: '100%' }}
|
||||
/>
|
||||
{/* real table data here */}
|
||||
</GraphBase>
|
||||
);
|
||||
}
|
||||
|
||||
export default ElecCost;
|
||||
|
||||
function getOptions(period, trend) {
|
||||
if (trend[period].length === 0) return null;
|
||||
const colors = [
|
||||
"#FFD160",
|
||||
"#12FFF5",
|
||||
"#2760FF",
|
||||
"#E80091",
|
||||
"#8064ff",
|
||||
"#ff8a3b",
|
||||
"#8cd26d",
|
||||
"#2aa1ff",
|
||||
];
|
||||
return {
|
||||
color: colors,
|
||||
grid: { top: 40, right: 12, bottom: 20, left: 80 },
|
||||
legend: {
|
||||
show: false,
|
||||
icon: "roundRect",
|
||||
top: 10,
|
||||
right: 10,
|
||||
padding: 0,
|
||||
itemWidth: 8,
|
||||
itemHeight: 8,
|
||||
itemGap: 3,
|
||||
height: 8,
|
||||
textStyle: {
|
||||
color: "#DFF1FE",
|
||||
fontSize: 12,
|
||||
},
|
||||
},
|
||||
xAxis: {
|
||||
type: "category",
|
||||
data: trend[period].map((item) => item.time),
|
||||
// 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: 14,
|
||||
},
|
||||
axisTick: { show: false },
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
width: 1,
|
||||
color: "#213259",
|
||||
},
|
||||
},
|
||||
},
|
||||
yAxis: {
|
||||
name: "单位/kWh",
|
||||
nameTextStyle: {
|
||||
color: "#fff",
|
||||
fontSize: 16,
|
||||
align: "right",
|
||||
},
|
||||
type: "value",
|
||||
axisLabel: {
|
||||
color: "#fff",
|
||||
fontSize: 14,
|
||||
formatter: "{value}",
|
||||
},
|
||||
axisLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
color: "#213259",
|
||||
},
|
||||
},
|
||||
splitLine: {
|
||||
lineStyle: {
|
||||
color: "#213259a0",
|
||||
},
|
||||
},
|
||||
},
|
||||
series: {
|
||||
// !(item.value == null || isNaN(+item.value)) ? (+item.value).toFixed(2) : null
|
||||
data: trend[period].map((item) =>
|
||||
item.qty == null || isNaN(+item.qty) ? null : (+item.qty).toFixed(2)
|
||||
),
|
||||
type: "line",
|
||||
symbol: "circle",
|
||||
symbolSize: 6,
|
||||
areaStyle: {
|
||||
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
||||
{ offset: 0, color: colors[0] + "40" },
|
||||
{ offset: 0.5, color: colors[0] + "20" },
|
||||
{ offset: 1, color: colors[0] + "00" },
|
||||
]),
|
||||
},
|
||||
},
|
||||
// series: seriesData.map((arr, index) => ({
|
||||
// name: index + 1 + '#' + name,
|
||||
// data: arr,
|
||||
// type: 'line',
|
||||
// areaStyle: {
|
||||
// color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
||||
// { offset: 0, color: colors[index] + '40' },
|
||||
// { offset: 0.5, color: colors[index] + '20' },
|
||||
// { offset: 1, color: colors[index] + '00' },
|
||||
// ]),
|
||||
// },
|
||||
// })),
|
||||
tooltip: {
|
||||
trigger: "axis",
|
||||
axisPointer: {
|
||||
type: "shadow",
|
||||
},
|
||||
className: "xc-chart-tooltip",
|
||||
},
|
||||
};
|
||||
}
|
||||
|
@ -1,165 +1,44 @@
|
||||
import cls from "./index.module.css";
|
||||
import GradientText from "../../../Common/GradientText";
|
||||
import { useSelector } from "react-redux";
|
||||
import { useEffect, useState } from "react";
|
||||
import cls from './index.module.css';
|
||||
import GradientText from '../../../Common/GradientText';
|
||||
|
||||
function Energy(props) {
|
||||
const [isPage1, setIsPage1] = useState(true);
|
||||
const energyInfo = useSelector((state) => state.energy?.info);
|
||||
return (
|
||||
<div className={' ' + cls.layout} style={{ color: '#fff' }}>
|
||||
<span
|
||||
className={cls.shadowBorder}
|
||||
style={{
|
||||
gridRow: '1 / 3',
|
||||
paddingTop: '38px',
|
||||
paddingLeft: '32px',
|
||||
userSelect: 'none',
|
||||
}}
|
||||
>
|
||||
<GradientText text="能源" />
|
||||
</span>
|
||||
<span
|
||||
className={cls.shadowBorder + ' ' + cls.infoText}
|
||||
style={{
|
||||
gridRow: '1 / 3',
|
||||
}}
|
||||
>
|
||||
<span style={{ lineHeight: 2.5 }}>余热发电</span>
|
||||
<span style={{ lineHeight: 2.5 }}>992Kwh</span>
|
||||
</span>
|
||||
|
||||
useEffect(() => {
|
||||
const timer = setInterval(() => {
|
||||
setIsPage1((pre) => !pre);
|
||||
}, 10000);
|
||||
|
||||
return () => {
|
||||
clearInterval(timer);
|
||||
}
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className={" " + cls.layout} style={{ color: "#fff" }}>
|
||||
<span
|
||||
className={cls.shadowBorder}
|
||||
style={{
|
||||
gridRow: "1 / 3",
|
||||
paddingTop: "104px",
|
||||
paddingLeft: "32px",
|
||||
userSelect: "none",
|
||||
}}
|
||||
>
|
||||
<GradientText text="能源" />
|
||||
</span>
|
||||
{!isPage1 && (
|
||||
<div
|
||||
style={{
|
||||
gridRow: "1 / 3",
|
||||
gridColumn: "2 / 5",
|
||||
display: "grid",
|
||||
gridTemplateRows: "1fr 1fr",
|
||||
gridTemplateColumns: "1fr 1fr",
|
||||
gap: "6px",
|
||||
}}
|
||||
>
|
||||
<div className={cls.shadowBorder + " " + cls.infoText}>
|
||||
<span style={{ lineHeight: 1.5 }}>智慧能源光伏发电(昨日)/kWh</span>
|
||||
<span
|
||||
style={{
|
||||
lineHeight: 1.5,
|
||||
width: "180px",
|
||||
wordWrap: "break-word",
|
||||
}}
|
||||
>
|
||||
{(+energyInfo?.elecQty6)?.toFixed(2) || 0}
|
||||
</span>
|
||||
</div>
|
||||
<div className={cls.shadowBorder + " " + cls.infoText}>
|
||||
<span style={{ lineHeight: 1.5 }}>许昌安彩光伏发电(昨日)/kWh</span>
|
||||
<span
|
||||
style={{
|
||||
lineHeight: 1.5,
|
||||
width: "180px",
|
||||
wordWrap: "break-word",
|
||||
}}
|
||||
>
|
||||
{(+energyInfo?.elecQty7)?.toFixed(2) || 0}
|
||||
</span>
|
||||
</div>
|
||||
<div className={cls.shadowBorder + " " + cls.infoText}>
|
||||
<span style={{ lineHeight: 1.5 }}>智慧能源光伏发电(总量)/kWh</span>
|
||||
<span
|
||||
style={{
|
||||
lineHeight: 1.5,
|
||||
width: "180px",
|
||||
wordWrap: "break-word",
|
||||
}}
|
||||
>
|
||||
{(+energyInfo?.elecQty4)?.toFixed(2) || 0}
|
||||
</span>
|
||||
</div>
|
||||
<div className={cls.shadowBorder + " " + cls.infoText}>
|
||||
<span style={{ lineHeight: 1.5 }}>许昌安彩光伏发电(总量)/kWh</span>
|
||||
<span
|
||||
style={{
|
||||
lineHeight: 1.5,
|
||||
width: "180px",
|
||||
wordWrap: "break-word",
|
||||
}}
|
||||
>
|
||||
{(+energyInfo?.elecQty5)?.toFixed(2) || 0}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{isPage1 && (
|
||||
<>
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
gap: "6px",
|
||||
gridRow: "1 / 3",
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{ flex: 1 }}
|
||||
className={cls.shadowBorder + " " + cls.infoText}
|
||||
>
|
||||
<span style={{ lineHeight: 1.5 }}>余热发电(实时)/kWh</span>
|
||||
<span
|
||||
style={{
|
||||
lineHeight: 1.5,
|
||||
width: "180px",
|
||||
wordWrap: "break-word",
|
||||
}}
|
||||
>
|
||||
{(+energyInfo?.elecQty1)?.toFixed(2) || 0}
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
style={{ flex: 1 }}
|
||||
className={cls.shadowBorder + " " + cls.infoText}
|
||||
>
|
||||
<span style={{ lineHeight: 1.5 }}>余热发电(总量)/kWh</span>
|
||||
<span
|
||||
style={{
|
||||
lineHeight: 1.5,
|
||||
width: "180px",
|
||||
wordWrap: "break-word",
|
||||
}}
|
||||
>
|
||||
{(+energyInfo?.elecQty3)?.toFixed(2) || 0}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<span className={cls.shadowBorder + " " + cls.infoText}>
|
||||
<span style={{ lineHeight: 1.5 }}>水耗量/Km³</span>
|
||||
<span style={{ lineHeight: 1.5 }}>
|
||||
{(+energyInfo?.waterQty)?.toFixed(2) || 0}
|
||||
</span>
|
||||
</span>
|
||||
<span className={cls.shadowBorder + " " + cls.infoText}>
|
||||
<span style={{ lineHeight: 1.5 }}>天然气I/Nm³</span>
|
||||
<span style={{ lineHeight: 1.5 }}>
|
||||
{energyInfo?.ngQty1?.replace("Nm³", "") || "0Nm³"}
|
||||
</span>
|
||||
</span>
|
||||
<span className={cls.shadowBorder + " " + cls.infoText}>
|
||||
<span style={{ lineHeight: 1.5 }}>电耗量/kWh</span>
|
||||
<span style={{ lineHeight: 1.5 }}>
|
||||
{(+energyInfo?.elecQty2)?.toFixed(2) || 0}
|
||||
</span>
|
||||
</span>
|
||||
<span className={cls.shadowBorder + " " + cls.infoText}>
|
||||
<span style={{ lineHeight: 1.5 }}>天然气II/Nm³</span>
|
||||
<span style={{ lineHeight: 1.5 }}>
|
||||
{energyInfo?.ngQty2?.replace("Nm³", "") || "0Nm³"}
|
||||
</span>
|
||||
</span>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
<span className={cls.shadowBorder + ' ' + cls.infoText}>
|
||||
水耗量: 32Km³
|
||||
</span>
|
||||
<span className={cls.shadowBorder + ' ' + cls.infoText}>
|
||||
天然气I: 92m³
|
||||
</span>
|
||||
<span className={cls.shadowBorder + ' ' + cls.infoText}>
|
||||
电耗量: 92Km³
|
||||
</span>
|
||||
<span className={cls.shadowBorder + ' ' + cls.infoText}>
|
||||
天然气II: 92m³
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default Energy;
|
||||
|
@ -1,32 +1,21 @@
|
||||
.layout {
|
||||
display: grid;
|
||||
gap: 6px;
|
||||
/* grid-template-columns: 133px 158px 292px 292px; */
|
||||
grid-template-columns: 125px 250px 250px 250px;
|
||||
/* grid-template-rows: 60px 60px; */
|
||||
grid-template-rows: 129px 129px;
|
||||
display: grid;
|
||||
gap: 6px;
|
||||
grid-template-columns: 133px 158px 292px 292px ;
|
||||
grid-template-rows: 60px 60px;
|
||||
}
|
||||
|
||||
.shadowBorder {
|
||||
box-shadow: inset 0 0 12px 3px #fff2;
|
||||
border-radius: 4px;
|
||||
padding: 4px;
|
||||
box-shadow: inset 0 0 12px 3px #fff3;
|
||||
border-radius: 4px;
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
.infoText {
|
||||
text-align: center;
|
||||
font-size: 22px;
|
||||
line-height: 2.5;
|
||||
/* line-height: 20px; */
|
||||
letter-spacing: 1px;
|
||||
user-select: none;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.infoText > span:last-child {
|
||||
color: #00FFF7;
|
||||
font-size: 24px;
|
||||
text-align: center;
|
||||
font-size: 24px;
|
||||
line-height: 2.2;
|
||||
/* line-height: 20px; */
|
||||
letter-spacing: 1px;
|
||||
user-select: none;
|
||||
}
|
||||
|
@ -1,172 +1,44 @@
|
||||
import GraphBase from "../../../Common/GraphBase";
|
||||
import ReactECharts from "echarts-for-react";
|
||||
// import getOptions from "../../../../hooks/getChartOption";
|
||||
import { useSelector } from "react-redux";
|
||||
import { useState } from "react";
|
||||
import * as echarts from "echarts";
|
||||
import dayjs from "dayjs";
|
||||
import GraphBase from '../../../Common/GraphBase';
|
||||
import ReactECharts from 'echarts-for-react';
|
||||
import getOptions from '../../../../hooks/getChartOption';
|
||||
|
||||
function NO(props) {
|
||||
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);
|
||||
const [period, setPeriod] = useState("日");
|
||||
const [timestr, setTimestr] = useState(
|
||||
dayjs().subtract(7, "day").format("YYYY.MM.DD") +
|
||||
" - " +
|
||||
dayjs().subtract(1, "day").format("YYYY.MM.DD")
|
||||
);
|
||||
function handleSwitch(v) {
|
||||
console.log('switched ', v);
|
||||
}
|
||||
|
||||
const currentTrend =
|
||||
period === "日"
|
||||
? dayTrend
|
||||
: period === "周"
|
||||
? weekTrend
|
||||
: period === "月"
|
||||
? monthTrend
|
||||
: yearTrend;
|
||||
function handleDateChange(v) {
|
||||
console.log('date ', v);
|
||||
}
|
||||
|
||||
const options = getOptions("NOX_float", period, currentTrend);
|
||||
|
||||
function handleSwitch(v) {}
|
||||
|
||||
function handleDateChange(value) {
|
||||
setPeriod(value);
|
||||
setTimestr(
|
||||
{
|
||||
日:
|
||||
dayjs().subtract(1, "day").format("YYYY.MM.DD") +
|
||||
" 7点 - " +
|
||||
dayjs().format("YYYY.MM.DD") +
|
||||
" 7点",
|
||||
年:
|
||||
dayjs().subtract(1, "year").endOf("year").format("YYYY.MM.") +
|
||||
"29 - " +
|
||||
dayjs().endOf("year").format("YYYY.MM.") +
|
||||
"28",
|
||||
周:
|
||||
dayjs().subtract(7, "day").format("YYYY.MM.DD") +
|
||||
" - " +
|
||||
dayjs().subtract(1, "day").format("YYYY.MM.DD"),
|
||||
月:
|
||||
dayjs().subtract(1, "month").format("YYYY.MM.") +
|
||||
"29 - " +
|
||||
dayjs().format("YYYY.MM.") +
|
||||
"28",
|
||||
}[value]
|
||||
);
|
||||
}
|
||||
return (
|
||||
<GraphBase
|
||||
icon="smoke"
|
||||
title="氮氧化物"
|
||||
desc={`能耗趋势图 ${timestr}`}
|
||||
switchOptions={false}
|
||||
defaultSelect={period}
|
||||
onSwitch={handleSwitch}
|
||||
dateOptions={["日", "周", "月", "年"]}
|
||||
onDateChange={handleDateChange}
|
||||
size={["long", "middle"]}
|
||||
>
|
||||
{options && (
|
||||
<ReactECharts
|
||||
key={Math.random()}
|
||||
option={options}
|
||||
style={{ height: "100%" }}
|
||||
/>
|
||||
)}
|
||||
{!options && (
|
||||
<p
|
||||
style={{
|
||||
color: "#cccf",
|
||||
fontSize: "24px",
|
||||
userSelect: "none",
|
||||
textAlign: "center",
|
||||
paddingTop: "96px",
|
||||
}}
|
||||
>
|
||||
暂无数据
|
||||
</p>
|
||||
)}
|
||||
</GraphBase>
|
||||
);
|
||||
return (
|
||||
<GraphBase
|
||||
icon="battery"
|
||||
title="一氧化氮"
|
||||
desc="能耗趋势图"
|
||||
switchOptions={true}
|
||||
onSwitch={handleSwitch}
|
||||
dateOptions={['日', '周', '月', '年']}
|
||||
legend={['总量', '白班', '夜班']}
|
||||
onDateChange={handleDateChange}
|
||||
size={['long', 'middle']}
|
||||
>
|
||||
{/* real echarts here */}
|
||||
<ReactECharts
|
||||
key={Math.random()}
|
||||
option={getOptions(
|
||||
[
|
||||
[148, 110, 140, 122, 84, 153, 89],
|
||||
[88, 79, 75, 73, 33, 54, 31],
|
||||
[60, 31, 65, 49, 51, 99, 58],
|
||||
],
|
||||
'氧气',
|
||||
)}
|
||||
style={{ height: '100%' }}
|
||||
/>
|
||||
{/* real table data here */}
|
||||
</GraphBase>
|
||||
);
|
||||
}
|
||||
|
||||
export default NO;
|
||||
|
||||
function getOptions(source, period, trend) {
|
||||
if (
|
||||
trend[source].length == 0 ||
|
||||
trend[source].filter((item) => item.value).length == 0
|
||||
)
|
||||
return null;
|
||||
return {
|
||||
color: ["#FFD160", "#12FFF5", "#2760FF"],
|
||||
grid: { top: 40, right: 12, bottom: 20, left: 64 },
|
||||
xAxis: {
|
||||
type: "category",
|
||||
data: trend[source].map((item) => item.time),
|
||||
axisLabel: {
|
||||
color: "#fff",
|
||||
fontSize: 12,
|
||||
},
|
||||
axisTick: { show: false },
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
width: 1,
|
||||
color: "#213259",
|
||||
},
|
||||
},
|
||||
},
|
||||
yAxis: {
|
||||
name: "单位mg/m³",
|
||||
nameTextStyle: {
|
||||
color: "#fff",
|
||||
fontSize: 12,
|
||||
align: "right",
|
||||
},
|
||||
type: "value",
|
||||
axisLabel: {
|
||||
color: "#fff",
|
||||
fontSize: 12,
|
||||
formatter: "{value}",
|
||||
},
|
||||
axisLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
color: "#213259",
|
||||
},
|
||||
},
|
||||
splitLine: {
|
||||
lineStyle: {
|
||||
color: "#213259a0",
|
||||
},
|
||||
},
|
||||
},
|
||||
series: [
|
||||
{
|
||||
data: trend[source].map((item) =>
|
||||
!(item.value == null || isNaN(+item.value))
|
||||
? (+item.value).toFixed(2)
|
||||
: null
|
||||
),
|
||||
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" },
|
||||
]),
|
||||
},
|
||||
},
|
||||
],
|
||||
tooltip: {
|
||||
trigger: "axis",
|
||||
axisPointer: {
|
||||
type: "shadow",
|
||||
},
|
||||
className: "xc-chart-tooltip",
|
||||
},
|
||||
};
|
||||
}
|
||||
|
@ -1,174 +1,44 @@
|
||||
import GraphBase from "../../../Common/GraphBase";
|
||||
import ReactECharts from "echarts-for-react";
|
||||
// import getOptions from "../../../../hooks/getChartOption";
|
||||
import { useSelector } from "react-redux";
|
||||
import { useState } from "react";
|
||||
import * as echarts from "echarts";
|
||||
import dayjs from "dayjs";
|
||||
import GraphBase from '../../../Common/GraphBase';
|
||||
import ReactECharts from 'echarts-for-react';
|
||||
import getOptions from '../../../../hooks/getChartOption';
|
||||
|
||||
function Dust(props) {
|
||||
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);
|
||||
const [period, setPeriod] = useState("日");
|
||||
const [timestr, setTimestr] = useState(
|
||||
dayjs().subtract(7, "day").format("YYYY.MM.DD") +
|
||||
" - " +
|
||||
dayjs().subtract(1, "day").format("YYYY.MM.DD")
|
||||
);
|
||||
const currentTrend =
|
||||
period === "日"
|
||||
? dayTrend
|
||||
: period === "周"
|
||||
? weekTrend
|
||||
: period === "月"
|
||||
? monthTrend
|
||||
: yearTrend;
|
||||
function NO2(props) {
|
||||
function handleSwitch(v) {
|
||||
console.log('switched ', v);
|
||||
}
|
||||
|
||||
const options = getOptions("dust_float", period, currentTrend);
|
||||
function handleDateChange(v) {
|
||||
console.log('date ', v);
|
||||
}
|
||||
|
||||
function handleSwitch(v) {}
|
||||
|
||||
function handleDateChange(value) {
|
||||
setPeriod(value);
|
||||
setTimestr(
|
||||
{
|
||||
日:
|
||||
dayjs().subtract(1, "day").format("YYYY.MM.DD") +
|
||||
" 7点 - " +
|
||||
dayjs().format("YYYY.MM.DD") +
|
||||
" 7点",
|
||||
年:
|
||||
dayjs().subtract(1, "year").endOf("year").format("YYYY.MM.") +
|
||||
"29 - " +
|
||||
dayjs().endOf("year").format("YYYY.MM.") +
|
||||
"28",
|
||||
周:
|
||||
dayjs().subtract(7, "day").format("YYYY.MM.DD") +
|
||||
" - " +
|
||||
dayjs().subtract(1, "day").format("YYYY.MM.DD"),
|
||||
月:
|
||||
dayjs().subtract(1, "month").format("YYYY.MM.") +
|
||||
"29 - " +
|
||||
dayjs().format("YYYY.MM.") +
|
||||
"28",
|
||||
}[value]
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<GraphBase
|
||||
icon="smoke"
|
||||
title="颗粒物"
|
||||
desc={`能耗趋势图 ${timestr}`}
|
||||
switchOptions={false}
|
||||
defaultSelect={period}
|
||||
onSwitch={handleSwitch}
|
||||
dateOptions={["日", "周", "月", "年"]}
|
||||
onDateChange={handleDateChange}
|
||||
size={["long", "middle"]}
|
||||
>
|
||||
{options && (
|
||||
<ReactECharts
|
||||
key={Math.random()}
|
||||
option={options}
|
||||
style={{ height: "100%" }}
|
||||
/>
|
||||
)}
|
||||
{!options && (
|
||||
<p
|
||||
style={{
|
||||
color: "#cccf",
|
||||
fontSize: "24px",
|
||||
userSelect: "none",
|
||||
textAlign: "center",
|
||||
paddingTop: "96px",
|
||||
}}
|
||||
>
|
||||
暂无数据
|
||||
</p>
|
||||
)}
|
||||
</GraphBase>
|
||||
);
|
||||
return (
|
||||
<GraphBase
|
||||
icon="battery"
|
||||
title="二氧化氮"
|
||||
desc="能耗趋势图"
|
||||
switchOptions={true}
|
||||
onSwitch={handleSwitch}
|
||||
dateOptions={['日', '周', '月', '年']}
|
||||
legend={['总量', '白班', '夜班']}
|
||||
onDateChange={handleDateChange}
|
||||
size={['long', 'middle']}
|
||||
>
|
||||
{/* real echarts here */}
|
||||
<ReactECharts
|
||||
key={Math.random()}
|
||||
option={getOptions(
|
||||
[
|
||||
[91, 164, 88, 120, 167, 158, 43],
|
||||
[30, 75, 52, 43, 73, 66, 36],
|
||||
[61, 89, 36, 77, 94, 92, 7],
|
||||
],
|
||||
'氧气',
|
||||
)}
|
||||
style={{ height: '100%' }}
|
||||
/>
|
||||
{/* real table data here */}
|
||||
</GraphBase>
|
||||
);
|
||||
}
|
||||
|
||||
export default Dust;
|
||||
|
||||
function getOptions(source, period, trend) {
|
||||
if (
|
||||
trend[source].length == 0 ||
|
||||
trend[source].filter((item) => item.value).length == 0
|
||||
)
|
||||
return null;
|
||||
return {
|
||||
color: ["#FFD160", "#12FFF5", "#2760FF"],
|
||||
grid: { top: 40, right: 12, bottom: 20, left: 64 },
|
||||
xAxis: {
|
||||
type: "category",
|
||||
data: trend[source].map((item) => item.time),
|
||||
axisLabel: {
|
||||
color: "#fff",
|
||||
fontSize: 12,
|
||||
},
|
||||
axisTick: { show: false },
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
width: 1,
|
||||
color: "#213259",
|
||||
},
|
||||
},
|
||||
},
|
||||
yAxis: {
|
||||
name: "单位mg/m³",
|
||||
nameTextStyle: {
|
||||
color: "#fff",
|
||||
fontSize: 12,
|
||||
align: "right",
|
||||
},
|
||||
type: "value",
|
||||
axisLabel: {
|
||||
color: "#fff",
|
||||
fontSize: 12,
|
||||
formatter: "{value}",
|
||||
},
|
||||
axisLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
color: "#213259",
|
||||
},
|
||||
},
|
||||
splitLine: {
|
||||
lineStyle: {
|
||||
color: "#213259a0",
|
||||
},
|
||||
},
|
||||
},
|
||||
series: [
|
||||
{
|
||||
data: trend[source].map((item) =>
|
||||
!(item.value == null || isNaN(+item.value))
|
||||
? (+item.value).toFixed(2)
|
||||
: null
|
||||
),
|
||||
type: "line",
|
||||
symbol: "circle",
|
||||
symbolSize: 6,
|
||||
areaStyle: {
|
||||
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
||||
{ offset: 0, color: "#FFD16040" },
|
||||
{ offset: 0.5, color: "#FFD16020" },
|
||||
{ offset: 1, color: "#FFD16010" },
|
||||
]),
|
||||
},
|
||||
},
|
||||
],
|
||||
tooltip: {
|
||||
trigger: "axis",
|
||||
axisPointer: {
|
||||
type: "shadow",
|
||||
},
|
||||
className: "xc-chart-tooltip",
|
||||
},
|
||||
};
|
||||
}
|
||||
export default NO2;
|
||||
|
@ -1,224 +1,37 @@
|
||||
import GraphBase from "../../../Common/GraphBase";
|
||||
import ReactECharts from "echarts-for-react";
|
||||
// import getOptions from "../../../../hooks/getChartOption";
|
||||
import { useSelector } from "react-redux";
|
||||
import { useState } from "react";
|
||||
import * as echarts from "echarts";
|
||||
import { lunarYear } from "../../../../utils/energeChartOption";
|
||||
import dayjs from "dayjs";
|
||||
import GraphBase from '../../../Common/GraphBase';
|
||||
import ReactECharts from 'echarts-for-react';
|
||||
import getOptions from '../../../../hooks/getChartOption';
|
||||
|
||||
function NatGas(props) {
|
||||
const elecTrend = useSelector((state) => state.energy.trend.natGas1);
|
||||
const [period, setPeriod] = useState("周");
|
||||
const [timestr, setTimestr] = useState(
|
||||
dayjs().subtract(7, "day").format("YYYY.MM.DD") +
|
||||
" - " +
|
||||
dayjs().subtract(1, "day").format("YYYY.MM.DD")
|
||||
);
|
||||
function handleSwitch(v) {
|
||||
console.log('switched ', v);
|
||||
}
|
||||
|
||||
const options = getOptions(
|
||||
{ 周: "week", 月: "month", 年: "year" }[period],
|
||||
elecTrend ?? { week: [], month: [], year: [] }
|
||||
);
|
||||
function handleDateChange(v) {
|
||||
console.log('date ', v);
|
||||
}
|
||||
|
||||
function handleSwitch(v) {
|
||||
// console.log('switched ', v);
|
||||
}
|
||||
|
||||
function handleDateChange(value) {
|
||||
setPeriod(value);
|
||||
setTimestr(
|
||||
{
|
||||
年:
|
||||
dayjs().subtract(1, "year").endOf("year").format("YYYY.MM.") +
|
||||
"29 - " +
|
||||
dayjs().endOf("year").format("YYYY.MM.") +
|
||||
"28",
|
||||
周:
|
||||
dayjs().subtract(7, "day").format("YYYY.MM.DD") +
|
||||
" - " +
|
||||
dayjs().subtract(1, "day").format("YYYY.MM.DD"),
|
||||
月:
|
||||
dayjs().subtract(1, "month").format("YYYY.MM.") +
|
||||
"29 - " +
|
||||
dayjs().format("YYYY.MM.") +
|
||||
"28",
|
||||
}[value]
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<GraphBase
|
||||
icon="battery"
|
||||
title="天然气I"
|
||||
desc={`能耗趋势图 ${timestr}`}
|
||||
switchOptions={false}
|
||||
onSwitch={handleSwitch}
|
||||
defaultSelect={period}
|
||||
dateOptions={["周", "月", "年"]}
|
||||
// legend={["总量"]}
|
||||
onDateChange={handleDateChange}
|
||||
size={["long", "middle"]}
|
||||
>
|
||||
{/* real echarts here */}
|
||||
{options && (
|
||||
<ReactECharts
|
||||
key={Math.random()}
|
||||
option={options}
|
||||
// option={getOptions([[91, 69, 5, 10, 21, 46, 24]], "氧气")}
|
||||
style={{ height: "100%" }}
|
||||
/>
|
||||
)}
|
||||
{!options && (
|
||||
<p
|
||||
style={{
|
||||
color: "#cccf",
|
||||
fontSize: "24px",
|
||||
userSelect: "none",
|
||||
textAlign: "center",
|
||||
paddingTop: "88px",
|
||||
}}
|
||||
>
|
||||
暂无数据
|
||||
</p>
|
||||
)}
|
||||
{/* real table data here */}
|
||||
</GraphBase>
|
||||
);
|
||||
return (
|
||||
<GraphBase
|
||||
icon="battery"
|
||||
title="天然气"
|
||||
desc="能耗趋势图"
|
||||
switchOptions={true}
|
||||
onSwitch={handleSwitch}
|
||||
dateOptions={['日', '周', '月', '年']}
|
||||
legend={['总量']}
|
||||
onDateChange={handleDateChange}
|
||||
size={['long', 'short']}
|
||||
>
|
||||
{/* real echarts here */}
|
||||
<ReactECharts
|
||||
key={Math.random()}
|
||||
option={getOptions([[91, 69, 5, 10, 21, 46, 24]], '氧气')}
|
||||
style={{ height: '100%' }}
|
||||
/>
|
||||
{/* real table data here */}
|
||||
</GraphBase>
|
||||
);
|
||||
}
|
||||
|
||||
export default NatGas;
|
||||
|
||||
function getOptions(period, trend) {
|
||||
if (trend[period].length === 0) return null;
|
||||
// export default function getOptions(seriesData, name) {
|
||||
const today = new Date();
|
||||
const currentYear = today.getFullYear();
|
||||
const currentMonth = today.getMonth() + 1;
|
||||
let days = 30;
|
||||
if (period == "month") {
|
||||
if (currentMonth in [1, 3, 5, 7, 8, 10, 12]) {
|
||||
days = 31;
|
||||
} else if (currentMonth == 2) {
|
||||
days = lunarYear(currentYear) ? 29 : 28;
|
||||
}
|
||||
}
|
||||
const colors = [
|
||||
"#FFD160",
|
||||
"#12FFF5",
|
||||
"#2760FF",
|
||||
"#E80091",
|
||||
"#8064ff",
|
||||
"#ff8a3b",
|
||||
"#8cd26d",
|
||||
"#2aa1ff",
|
||||
];
|
||||
return {
|
||||
color: colors,
|
||||
grid: { top: 40, right: 12, bottom: 20, left: 80 },
|
||||
legend: {
|
||||
show: false,
|
||||
icon: "roundRect",
|
||||
top: 10,
|
||||
right: 10,
|
||||
padding: 0,
|
||||
itemWidth: 8,
|
||||
itemHeight: 8,
|
||||
itemGap: 3,
|
||||
height: 8,
|
||||
textStyle: {
|
||||
color: "#DFF1FE",
|
||||
fontSize: 12,
|
||||
},
|
||||
},
|
||||
xAxis: {
|
||||
type: "category",
|
||||
data: Array(period == "week" ? 7 : period == "year" ? 12 : days)
|
||||
.fill(1)
|
||||
.map((_, index) => {
|
||||
if (period == "week") {
|
||||
const dtimestamp = today - (index + 1) * 24 * 60 * 60 * 1000;
|
||||
return `${new Date(dtimestamp).getMonth() + 1}.${new Date(
|
||||
dtimestamp
|
||||
).getDate()}`;
|
||||
} else if (period == "month") {
|
||||
return `${currentMonth}.${days - index}`;
|
||||
} else {
|
||||
return `${currentYear}.${12 - index}`;
|
||||
}
|
||||
})
|
||||
.reverse(),
|
||||
axisLabel: {
|
||||
color: "#fff",
|
||||
fontSize: 14,
|
||||
},
|
||||
axisTick: { show: false },
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
width: 1,
|
||||
color: "#213259",
|
||||
},
|
||||
},
|
||||
},
|
||||
yAxis: {
|
||||
name: "单位/Nm³",
|
||||
nameTextStyle: {
|
||||
color: "#fff",
|
||||
fontSize: 16,
|
||||
align: "right",
|
||||
},
|
||||
type: "value",
|
||||
axisLabel: {
|
||||
color: "#fff",
|
||||
fontSize: 14,
|
||||
formatter: "{value}",
|
||||
},
|
||||
axisLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
color: "#213259",
|
||||
},
|
||||
},
|
||||
splitLine: {
|
||||
lineStyle: {
|
||||
color: "#213259a0",
|
||||
},
|
||||
},
|
||||
},
|
||||
series: {
|
||||
data: trend[period].map((item) =>
|
||||
item != null ? (+item).toFixed(2) : null
|
||||
),
|
||||
type: "line",
|
||||
symbol: "circle",
|
||||
symbolSize: 6,
|
||||
areaStyle: {
|
||||
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
||||
{ offset: 0, color: colors[0] + "40" },
|
||||
{ offset: 0.5, color: colors[0] + "20" },
|
||||
{ offset: 1, color: colors[0] + "00" },
|
||||
]),
|
||||
},
|
||||
},
|
||||
// series: seriesData.map((arr, index) => ({
|
||||
// name: index + 1 + '#' + name,
|
||||
// data: arr,
|
||||
// type: 'line',
|
||||
// areaStyle: {
|
||||
// color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
||||
// { offset: 0, color: colors[index] + '40' },
|
||||
// { offset: 0.5, color: colors[index] + '20' },
|
||||
// { offset: 1, color: colors[index] + '00' },
|
||||
// ]),
|
||||
// },
|
||||
// })),
|
||||
tooltip: {
|
||||
trigger: "axis",
|
||||
axisPointer: {
|
||||
type: "shadow",
|
||||
},
|
||||
className: "xc-chart-tooltip",
|
||||
// backgroundColor: ''
|
||||
},
|
||||
};
|
||||
}
|
||||
|
@ -1,186 +1,65 @@
|
||||
import GraphBase from "../../../Common/GraphBase";
|
||||
import ReactECharts from "echarts-for-react";
|
||||
// import getOptions from "../../../../hooks/getChartOption";
|
||||
import { useSelector } from "react-redux";
|
||||
import { useState } from "react";
|
||||
import * as echarts from "echarts";
|
||||
import dayjs from "dayjs";
|
||||
import GraphBase from '../../../Common/GraphBase';
|
||||
import ReactECharts from 'echarts-for-react';
|
||||
import getOptions from '../../../../hooks/getChartOption';
|
||||
|
||||
// function rand(max) {
|
||||
// return Math.ceil(Math.random() * max);
|
||||
// }
|
||||
// function getArr(len) {
|
||||
// return Array(len).fill(1).map(() => rand(100))
|
||||
// }
|
||||
// function getArrs(len) {
|
||||
// return Array(len).fill(1).map(() => getArr(7))
|
||||
// }
|
||||
// function fan4(...arrs) {
|
||||
// const total = arrs[0].map((_, i) =>
|
||||
// arrs.reduce((sum, arr) => sum + arr[i], 0),
|
||||
// );
|
||||
// arrs.unshift(total);
|
||||
// return arrs;
|
||||
// }
|
||||
// function main() {
|
||||
// // console.log(JSON.stringify(fan(getArrs(3))))
|
||||
// console.log(fan(getArrs(3)))
|
||||
// }
|
||||
|
||||
function Oxygen(props) {
|
||||
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);
|
||||
const [period, setPeriod] = useState("日");
|
||||
const [timestr, setTimestr] = useState(
|
||||
dayjs().subtract(7, "day").format("YYYY.MM.DD") +
|
||||
" - " +
|
||||
dayjs().subtract(1, "day").format("YYYY.MM.DD")
|
||||
);
|
||||
function handleSwitch(v) {
|
||||
console.log('switched ', v);
|
||||
}
|
||||
|
||||
const currentTrend =
|
||||
period === "日"
|
||||
? dayTrend
|
||||
: period === "周"
|
||||
? weekTrend
|
||||
: period === "月"
|
||||
? monthTrend
|
||||
: yearTrend;
|
||||
function handleDateChange(v) {
|
||||
console.log('date ', v);
|
||||
}
|
||||
|
||||
const options = getOptions("O2_float", period, currentTrend);
|
||||
|
||||
function handleSwitch(v) {}
|
||||
|
||||
function handleDateChange(value) {
|
||||
setPeriod(value);
|
||||
setTimestr(
|
||||
{
|
||||
日:
|
||||
dayjs().subtract(1, "day").format("YYYY.MM.DD") +
|
||||
" 7点 - " +
|
||||
dayjs().format("YYYY.MM.DD") +
|
||||
" 7点",
|
||||
年:
|
||||
dayjs().subtract(1, "year").endOf("year").format("YYYY.MM.") +
|
||||
"29 - " +
|
||||
dayjs().endOf("year").format("YYYY.MM.") +
|
||||
"28",
|
||||
周:
|
||||
dayjs().subtract(7, "day").format("YYYY.MM.DD") +
|
||||
" - " +
|
||||
dayjs().subtract(1, "day").format("YYYY.MM.DD"),
|
||||
月:
|
||||
dayjs().subtract(1, "month").format("YYYY.MM.") +
|
||||
"29 - " +
|
||||
dayjs().format("YYYY.MM.") +
|
||||
"28",
|
||||
}[value]
|
||||
);
|
||||
}
|
||||
return (
|
||||
<GraphBase
|
||||
icon="smoke"
|
||||
title="氧气含量"
|
||||
desc={`能耗趋势图 ${timestr}`}
|
||||
switchOptions={false}
|
||||
defaultSelect={period}
|
||||
onSwitch={handleSwitch}
|
||||
dateOptions={["日", "周", "月", "年"]}
|
||||
onDateChange={handleDateChange}
|
||||
size={["long", "middle"]}
|
||||
>
|
||||
{options && (
|
||||
<ReactECharts
|
||||
key={Math.random()}
|
||||
option={options}
|
||||
style={{ height: "100%" }}
|
||||
/>
|
||||
)}
|
||||
{!options && (
|
||||
<p
|
||||
style={{
|
||||
color: "#cccf",
|
||||
fontSize: "24px",
|
||||
userSelect: "none",
|
||||
textAlign: "center",
|
||||
paddingTop: "160px",
|
||||
}}
|
||||
>
|
||||
暂无数据
|
||||
</p>
|
||||
)}
|
||||
</GraphBase>
|
||||
);
|
||||
return (
|
||||
<GraphBase
|
||||
icon="battery"
|
||||
title="氧气含量"
|
||||
desc="能耗趋势图"
|
||||
switchOptions={true}
|
||||
onSwitch={handleSwitch}
|
||||
dateOptions={['日', '周', '月', '年']}
|
||||
legend={['总量', '白班', '夜班']}
|
||||
onDateChange={handleDateChange}
|
||||
size={['long', 'middle']}
|
||||
>
|
||||
{/* real echarts here */}
|
||||
<ReactECharts
|
||||
key={Math.random()}
|
||||
option={getOptions(
|
||||
[
|
||||
[172, 165, 135, 35, 101, 53, 68], // 总量
|
||||
[87, 68, 81, 33, 35, 44, 38], // 白班
|
||||
[85, 97, 54, 2, 66, 9, 30], // 夜班
|
||||
],
|
||||
'氧气',
|
||||
)}
|
||||
style={{ height: '100%' }}
|
||||
/>
|
||||
{/* real table data here */}
|
||||
</GraphBase>
|
||||
);
|
||||
}
|
||||
|
||||
export default Oxygen;
|
||||
|
||||
function getOptions(source, period, trend) {
|
||||
if (
|
||||
trend[source].length == 0 ||
|
||||
trend[source].filter((item) => item.value).length == 0
|
||||
)
|
||||
return null;
|
||||
return {
|
||||
color: ["#FFD160", "#12FFF5", "#2760FF"],
|
||||
grid: { top: 40, right: 12, bottom: 20, left: 80 },
|
||||
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: "单位/%",
|
||||
nameTextStyle: {
|
||||
color: "#fff",
|
||||
fontSize: 16,
|
||||
align: "right",
|
||||
},
|
||||
type: "value",
|
||||
axisLabel: {
|
||||
color: "#fff",
|
||||
fontSize: 16,
|
||||
formatter: "{value} %",
|
||||
},
|
||||
min: 0,
|
||||
max: 100,
|
||||
axisLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
color: "#213259",
|
||||
},
|
||||
},
|
||||
splitLine: {
|
||||
lineStyle: {
|
||||
color: "#213259a0",
|
||||
},
|
||||
},
|
||||
},
|
||||
series: [
|
||||
{
|
||||
data: trend[source].map((item) =>
|
||||
!(item.value == null || isNaN(+item.value))
|
||||
? (+item.value).toFixed(2)
|
||||
: null
|
||||
),
|
||||
type: "line",
|
||||
symbol: "circle",
|
||||
symbolSize: 6,
|
||||
areaStyle: {
|
||||
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
||||
{ offset: 0, color: "#FFD16040" },
|
||||
{ offset: 0.5, color: "#FFD16020" },
|
||||
{ offset: 1, color: "#FFD16010" },
|
||||
]),
|
||||
},
|
||||
},
|
||||
],
|
||||
tooltip: {
|
||||
trigger: "axis",
|
||||
axisPointer: {
|
||||
type: "shadow",
|
||||
},
|
||||
className: "xc-chart-tooltip",
|
||||
},
|
||||
};
|
||||
}
|
||||
|
@ -4,11 +4,11 @@ import getOptions from '../../../../hooks/getChartOption';
|
||||
|
||||
function RestHeat(props) {
|
||||
function handleSwitch(v) {
|
||||
// console.log('switched ', v);
|
||||
console.log('switched ', v);
|
||||
}
|
||||
|
||||
function handleDateChange(v) {
|
||||
// console.log('date ', v);
|
||||
console.log('date ', v);
|
||||
}
|
||||
|
||||
return (
|
||||
|
@ -1,174 +1,44 @@
|
||||
import GraphBase from "../../../Common/GraphBase";
|
||||
import ReactECharts from "echarts-for-react";
|
||||
// import getOptions from "../../../../hooks/getChartOption";
|
||||
import { useSelector } from "react-redux";
|
||||
import { useState } from "react";
|
||||
import * as echarts from "echarts";
|
||||
import dayjs from "dayjs";
|
||||
import GraphBase from '../../../Common/GraphBase';
|
||||
import ReactECharts from 'echarts-for-react';
|
||||
import getOptions from '../../../../hooks/getChartOption';
|
||||
|
||||
function SO2(props) {
|
||||
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);
|
||||
const [period, setPeriod] = useState("日");
|
||||
function handleSwitch(v) {
|
||||
console.log('switched ', v);
|
||||
}
|
||||
|
||||
const currentTrend =
|
||||
period === "日"
|
||||
? dayTrend
|
||||
: period === "周"
|
||||
? weekTrend
|
||||
: period === "月"
|
||||
? monthTrend
|
||||
: yearTrend;
|
||||
const [timestr, setTimestr] = useState(
|
||||
dayjs().subtract(7, "day").format("YYYY.MM.DD") +
|
||||
" - " +
|
||||
dayjs().subtract(1, "day").format("YYYY.MM.DD")
|
||||
);
|
||||
const options = getOptions("SO2_float", period, currentTrend);
|
||||
function handleDateChange(v) {
|
||||
console.log('date ', v);
|
||||
}
|
||||
|
||||
function handleSwitch(v) {}
|
||||
|
||||
function handleDateChange(value) {
|
||||
setPeriod(value);
|
||||
setTimestr(
|
||||
{
|
||||
日:
|
||||
dayjs().subtract(1, "day").format("YYYY.MM.DD") +
|
||||
" 7点 - " +
|
||||
dayjs().format("YYYY.MM.DD") +
|
||||
" 7点",
|
||||
年:
|
||||
dayjs().subtract(1, "year").endOf("year").format("YYYY.MM.") +
|
||||
"29 - " +
|
||||
dayjs().endOf("year").format("YYYY.MM.") +
|
||||
"28",
|
||||
周:
|
||||
dayjs().subtract(7, "day").format("YYYY.MM.DD") +
|
||||
" - " +
|
||||
dayjs().subtract(1, "day").format("YYYY.MM.DD"),
|
||||
月:
|
||||
dayjs().subtract(1, "month").format("YYYY.MM.") +
|
||||
"29 - " +
|
||||
dayjs().format("YYYY.MM.") +
|
||||
"28",
|
||||
}[value]
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<GraphBase
|
||||
icon="smoke"
|
||||
title="二氧化硫"
|
||||
desc={`能耗趋势图 ${timestr}`}
|
||||
switchOptions={false}
|
||||
defaultSelect={period}
|
||||
onSwitch={handleSwitch}
|
||||
dateOptions={["日", "周", "月", "年"]}
|
||||
onDateChange={handleDateChange}
|
||||
size={["long", "middle"]}
|
||||
>
|
||||
{options && (
|
||||
<ReactECharts
|
||||
key={Math.random()}
|
||||
option={options}
|
||||
style={{ height: "100%" }}
|
||||
/>
|
||||
)}
|
||||
{!options && (
|
||||
<p
|
||||
style={{
|
||||
color: "#cccf",
|
||||
fontSize: "24px",
|
||||
userSelect: "none",
|
||||
textAlign: "center",
|
||||
paddingTop: "96px",
|
||||
}}
|
||||
>
|
||||
暂无数据
|
||||
</p>
|
||||
)}
|
||||
</GraphBase>
|
||||
);
|
||||
return (
|
||||
<GraphBase
|
||||
icon="battery"
|
||||
title="二氧化硫"
|
||||
desc="能耗趋势图"
|
||||
switchOptions={true}
|
||||
onSwitch={handleSwitch}
|
||||
dateOptions={['日', '周', '月', '年']}
|
||||
legend={['总量', '白班', '夜班']}
|
||||
onDateChange={handleDateChange}
|
||||
size={['long', 'middle']}
|
||||
>
|
||||
{/* real echarts here */}
|
||||
<ReactECharts
|
||||
key={Math.random()}
|
||||
option={getOptions(
|
||||
[
|
||||
[132, 155, 140, 83, 180, 67, 136],
|
||||
[83, 58, 60, 22, 80, 64, 43],
|
||||
[49, 97, 80, 61, 100, 3, 93],
|
||||
],
|
||||
'氧气',
|
||||
)}
|
||||
style={{ height: '100%' }}
|
||||
/>
|
||||
{/* real table data here */}
|
||||
</GraphBase>
|
||||
);
|
||||
}
|
||||
|
||||
export default SO2;
|
||||
|
||||
function getOptions(source, period, trend) {
|
||||
if (
|
||||
trend[source].length == 0 ||
|
||||
trend[source].filter((item) => item.value).length == 0
|
||||
)
|
||||
return null;
|
||||
return {
|
||||
color: ["#FFD160", "#12FFF5", "#2760FF"],
|
||||
grid: { top: 40, right: 12, bottom: 20, left: 64 },
|
||||
xAxis: {
|
||||
type: "category",
|
||||
data: trend[source].map((item) => item.time),
|
||||
axisLabel: {
|
||||
color: "#fff",
|
||||
fontSize: 12,
|
||||
},
|
||||
axisTick: { show: false },
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
width: 1,
|
||||
color: "#213259",
|
||||
},
|
||||
},
|
||||
},
|
||||
yAxis: {
|
||||
name: "单位mg/m³",
|
||||
nameTextStyle: {
|
||||
color: "#fff",
|
||||
fontSize: 12,
|
||||
align: "right",
|
||||
},
|
||||
type: "value",
|
||||
axisLabel: {
|
||||
color: "#fff",
|
||||
fontSize: 12,
|
||||
formatter: "{value}",
|
||||
},
|
||||
axisLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
color: "#213259",
|
||||
},
|
||||
},
|
||||
splitLine: {
|
||||
lineStyle: {
|
||||
color: "#213259a0",
|
||||
},
|
||||
},
|
||||
},
|
||||
series: [
|
||||
{
|
||||
data: trend[source].map((item) =>
|
||||
!(item.value == null || isNaN(+item.value))
|
||||
? (+item.value).toFixed(2)
|
||||
: null
|
||||
),
|
||||
type: "line",
|
||||
symbol: "circle",
|
||||
symbolSize: 6,
|
||||
areaStyle: {
|
||||
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
||||
{ offset: 0, color: "#FFD16040" },
|
||||
{ offset: 0.5, color: "#FFD16020" },
|
||||
{ offset: 1, color: "#FFD16010" },
|
||||
]),
|
||||
},
|
||||
},
|
||||
],
|
||||
tooltip: {
|
||||
trigger: "axis",
|
||||
axisPointer: {
|
||||
type: "shadow",
|
||||
},
|
||||
className: "xc-chart-tooltip",
|
||||
},
|
||||
};
|
||||
}
|
||||
|
@ -1,51 +1,37 @@
|
||||
import cls from "./index.module.css";
|
||||
import GradientText from "../../../Common/GradientText";
|
||||
import { useSelector } from "react-redux";
|
||||
import cls from './index.module.css';
|
||||
import GradientText from '../../../Common/GradientText';
|
||||
|
||||
function SmokeHandle(props) {
|
||||
const smokeInfo = useSelector((state) => state.smoke?.info);
|
||||
return (
|
||||
<div className={" " + cls.smoke} style={{ color: "#fff" }}>
|
||||
<span
|
||||
className={cls.shadowBorder}
|
||||
style={{
|
||||
gridRow: "1 / 3",
|
||||
paddingTop: "96px",
|
||||
paddingLeft: "32px",
|
||||
userSelect: "none",
|
||||
}}
|
||||
>
|
||||
<GradientText text="烟气处理" />
|
||||
</span>
|
||||
<span
|
||||
className={cls.shadowBorder + " " + cls.infoText}
|
||||
style={{ letterSpacing: "2px" }}
|
||||
>
|
||||
<span style={{ lineHeight: 1.5 }}>氧气含量 %</span>
|
||||
<span style={{ lineHeight: 1.5 }}>
|
||||
{(+smokeInfo?.O2_float)?.toFixed(2) || 0}
|
||||
</span>
|
||||
</span>
|
||||
<span className={cls.shadowBorder + " " + cls.infoText}>
|
||||
<span style={{ lineHeight: 1.5 }}>氮氧化物浓度 mg/m³</span>
|
||||
<span style={{ lineHeight: 1.5 }}>
|
||||
{(+smokeInfo?.NOX_float)?.toFixed(2) || 0}
|
||||
</span>
|
||||
</span>
|
||||
<span className={cls.shadowBorder + " " + cls.infoText}>
|
||||
<span style={{ lineHeight: 1.5 }}>二氧化硫浓度 mg/m³</span>
|
||||
<span style={{ lineHeight: 1.5 }}>
|
||||
{(+smokeInfo?.SO2_float)?.toFixed(2) || 0}
|
||||
</span>
|
||||
</span>
|
||||
<span className={cls.shadowBorder + " " + cls.infoText}>
|
||||
<span style={{ lineHeight: 1.5 }}>颗粒物浓度 mg/m³</span>
|
||||
<span style={{ lineHeight: 1.5 }}>
|
||||
{(+smokeInfo?.dust_float)?.toFixed(2) || 0}
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
return (
|
||||
<div className={' ' + cls.smoke} style={{ color: '#fff' }}>
|
||||
<span
|
||||
className={cls.shadowBorder}
|
||||
style={{
|
||||
gridRow: '1 / 3',
|
||||
paddingTop: '38px',
|
||||
paddingLeft: '32px',
|
||||
userSelect: 'none',
|
||||
}}
|
||||
>
|
||||
<GradientText text="烟气处理" />
|
||||
</span>
|
||||
<span
|
||||
className={cls.shadowBorder + ' ' + cls.infoText}
|
||||
style={{ letterSpacing: '12px' }}
|
||||
>
|
||||
氧气含量: <span style={{ letterSpacing: '1px' }}>80%</span>
|
||||
</span>
|
||||
<span className={cls.shadowBorder + ' ' + cls.infoText}>
|
||||
一氧化氮排放浓度: 20mg/m³
|
||||
</span>
|
||||
<span className={cls.shadowBorder + ' ' + cls.infoText}>
|
||||
二氧化硫排放浓度: 20mg/m³
|
||||
</span>
|
||||
<span className={cls.shadowBorder + ' ' + cls.infoText}>
|
||||
二氧化氮排放浓度: 20mg/m³
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default SmokeHandle;
|
||||
|
@ -1,32 +1,21 @@
|
||||
.smoke {
|
||||
display: grid;
|
||||
gap: 6px;
|
||||
grid-template-columns: 187px 347px 347px;
|
||||
/* grid-template-rows: 60px 60px; */
|
||||
grid-template-rows: 129px 129px;
|
||||
height: 100%;
|
||||
display: grid;
|
||||
gap: 6px;
|
||||
grid-template-columns: 187px 347px 347px ;
|
||||
grid-template-rows: 60px 60px;
|
||||
}
|
||||
|
||||
.shadowBorder {
|
||||
box-shadow: inset 0 0 12px 3px #fff2;
|
||||
border-radius: 4px;
|
||||
padding: 4px;
|
||||
box-shadow: inset 0 0 12px 3px #fff3;
|
||||
border-radius: 4px;
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
.infoText {
|
||||
text-align: center;
|
||||
font-size: 24px;
|
||||
line-height: 2.5;
|
||||
/* line-height: 20px; */
|
||||
letter-spacing: 1px;
|
||||
user-select: none;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.infoText > span:last-child {
|
||||
color: #00fff7;
|
||||
font-size: 28px;
|
||||
text-align: center;
|
||||
font-size: 24px;
|
||||
line-height: 2.2;
|
||||
/* line-height: 20px; */
|
||||
letter-spacing: 1px;
|
||||
user-select: none;
|
||||
}
|
||||
|
@ -4,11 +4,11 @@ import getOptions from '../../../../hooks/getChartOption';
|
||||
|
||||
function WaterCost(props) {
|
||||
function handleSwitch(v) {
|
||||
// console.log('switched ', v);
|
||||
console.log('switched ', v);
|
||||
}
|
||||
|
||||
function handleDateChange(v) {
|
||||
// console.log('date ', v);
|
||||
console.log('date ', v);
|
||||
}
|
||||
|
||||
return (
|
||||
|
@ -1,6 +1,6 @@
|
||||
import React from 'react';
|
||||
import CurrentTemp from '../../../Common/CurrentTemp';
|
||||
import WindFrequence from '../../../Common/AnnealFanRunFrequence';
|
||||
import WindFrequence from '../../../Common/FanRunFrequence';
|
||||
|
||||
import { motion } from 'framer-motion';
|
||||
|
||||
@ -19,7 +19,7 @@ export default function index() {
|
||||
<CurrentTemp style={{ width: '100%' }} />
|
||||
</div>
|
||||
<div style={{ flex: 1, marginTop: '24px', width: '100%' }}>
|
||||
<WindFrequence stretch={true} />
|
||||
<WindFrequence />
|
||||
</div>
|
||||
</motion.div>
|
||||
);
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { motion } from 'framer-motion';
|
||||
import FanInfo from '../../../Common/FanInfoStretch';
|
||||
import FanInfo from '../../../Common/FanInfo';
|
||||
import cls from './index.module.scss';
|
||||
|
||||
export default function index() {
|
||||
@ -18,7 +18,7 @@ export default function index() {
|
||||
transition={{ type: 'tween' }}
|
||||
>
|
||||
<div style={{ flex: 1 }}>
|
||||
<FanInfo longBg={true} source="annealFanInfo" />
|
||||
<FanInfo longBg={true} rows={24} />
|
||||
</div>
|
||||
</motion.div>
|
||||
);
|
||||
|
@ -1,118 +1,32 @@
|
||||
import cls from "./righttable.module.scss";
|
||||
import { ScrollBoard } from "@jiaminghi/data-view-react";
|
||||
import { useSelector } from "react-redux";
|
||||
import React, { Component } from "react";
|
||||
import "./righttable.module.scss";
|
||||
|
||||
function CurrentSpec(props) {
|
||||
const rawData = useSelector((state) => state.cutting.productData);
|
||||
let config = {
|
||||
// headerBGC: "rgba(4, 44, 76, 0.3)",
|
||||
headerBGC: "#044A8460",
|
||||
header: [
|
||||
'<span style="color:#fff; padding-left: 8px;">产线名<span/>',
|
||||
'<span style="color:#fff; padding-left: 8px;">玻璃长度<span/>',
|
||||
'<span style="color:#fff; padding-left: 8px;">玻璃宽度<span/>',
|
||||
'<span style="color:#fff; padding-left: 8px;">玻璃厚度<span/>',
|
||||
],
|
||||
// oddRowBGC: "#042444",
|
||||
// evenRowBGC: "#042c4c",
|
||||
oddRowBGC: "#044A8460",
|
||||
evenRowBGC: "#0b549970",
|
||||
columnWidth: [90],
|
||||
rowNum: 3,
|
||||
hoverPause: true,
|
||||
headerHeight: 40,
|
||||
data: replaceStyle(filterData(rawData), 0.8),
|
||||
};
|
||||
// import { ScrollBoard } from '@jiaminghi/data-view-react';
|
||||
|
||||
return (
|
||||
<div className={cls.CenterChart1itemDetailBorder} style={{ opacity: 0.75 }}>
|
||||
<h2 className={cls.CenterChart1itemTXT}>当前产线生产规格</h2>
|
||||
<div className={cls.TableContainer}>
|
||||
{config.data.length !== 0 && <ScrollBoard config={config} style={{}} />}
|
||||
{config.data.length === 0 && (
|
||||
<p
|
||||
style={{
|
||||
color: "#cccf",
|
||||
fontSize: "24px",
|
||||
userSelect: "none",
|
||||
textAlign: "center",
|
||||
paddingTop: "36px",
|
||||
}}
|
||||
>
|
||||
暂无数据
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default CurrentSpec;
|
||||
|
||||
// 测试数据
|
||||
var rawData = [
|
||||
{
|
||||
id: 1,
|
||||
length: 1209,
|
||||
productionLine: "Y61",
|
||||
square: 123.3,
|
||||
thick: 2,
|
||||
wide: 1089,
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
length: 1119,
|
||||
productionLine: "Y62",
|
||||
square: 103.3,
|
||||
thick: 2,
|
||||
wide: 1339,
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
length: 1019,
|
||||
productionLine: "Y63",
|
||||
square: 233,
|
||||
thick: 1,
|
||||
wide: 1111,
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
length: 2000,
|
||||
productionLine: "Y64",
|
||||
square: 233,
|
||||
thick: 1,
|
||||
wide: 1232,
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
length: 1560,
|
||||
productionLine: "Y65",
|
||||
square: 233,
|
||||
thick: 1,
|
||||
wide: 996,
|
||||
},
|
||||
{
|
||||
id: 6,
|
||||
length: 1990,
|
||||
productionLine: "Y66",
|
||||
square: 233,
|
||||
thick: 1,
|
||||
wide: 416,
|
||||
},
|
||||
let data = [
|
||||
["产线0", "10mm", "10mm", "10mm"],
|
||||
["产线2", "8mm", "8mm", "8mm"],
|
||||
["产线3", "15mm", "15mm", "15mm"],
|
||||
["产线4", "15mm", "15mm", "15mm"],
|
||||
];
|
||||
|
||||
function filterData(rawData) {
|
||||
return (rawData ?? []).map((item) => [
|
||||
// 产线名
|
||||
item.productionLine,
|
||||
// 原板宽度
|
||||
item.length,
|
||||
// 净板宽
|
||||
item.wide,
|
||||
// 玻璃厚度
|
||||
item.thick,
|
||||
]);
|
||||
}
|
||||
let header = ["产线名", "原板宽度", "净板宽", "玻璃厚度"];
|
||||
|
||||
let config = {
|
||||
headerBGC: "rgba(4, 44, 76, 0.3)",
|
||||
header: [
|
||||
'<span style="color:#fff">产线名<span/>',
|
||||
'<span style="color:#fff">原板宽度<span/>',
|
||||
'<span style="color:#fff">净板宽<span/>',
|
||||
'<span style="color:#fff">玻璃厚度<span/>',
|
||||
],
|
||||
oddRowBGC: "#042444",
|
||||
evenRowBGC: "#042c4c",
|
||||
columnWidth: [90],
|
||||
headerHeight: 40,
|
||||
hoverPause: false,
|
||||
data: replaceStyle(data, 0.7),
|
||||
};
|
||||
|
||||
function replaceStyle(Arr, opencity) {
|
||||
let temp = [];
|
||||
@ -120,11 +34,32 @@ function replaceStyle(Arr, opencity) {
|
||||
for (let i = 0; i < Arr.length; i++) {
|
||||
temp[i] = [];
|
||||
for (let j = 0; j < Arr[i].length; j++) {
|
||||
temp[i][j] = `<span style="color:rgba(255, 255, 255,${opencity})">${
|
||||
Arr[i][j]
|
||||
} ${j == 0 ? "" : "mm"}<span/>`;
|
||||
temp[i][
|
||||
j
|
||||
] = ` <span style="color:rgba(255, 255, 255,${opencity})">${Arr[i][j]}<span/>`;
|
||||
}
|
||||
}
|
||||
|
||||
return temp;
|
||||
}
|
||||
|
||||
class Chart1 extends Component {
|
||||
render() {
|
||||
return (
|
||||
<div className="CenterChart1itemDetailBorder" style={{ opacity: 0.75 }}>
|
||||
<h2 className="CenterChart1itemTXT"> 当前产线生产规格</h2>
|
||||
<div className="CenterChart1itemContainer">
|
||||
<span className="CenterFormitemDetailBorderLine1"></span>
|
||||
<span className="CenterFormitemDetailBorderLine2"></span>
|
||||
<span className="CenterFormitemDetailBorderLine3"></span>
|
||||
{/* <ScrollBoard
|
||||
config={config}
|
||||
style={{ width: '105%', height: '240%' }}
|
||||
/> */}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default Chart1;
|
||||
|
@ -1,23 +1,50 @@
|
||||
.CenterChart1itemDetailBorder {
|
||||
width: 100%;
|
||||
height: 200px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: flex-start;
|
||||
color: #fff;
|
||||
background-color: rgba(4, 44, 76, 0.2);
|
||||
width: 100%;
|
||||
height: 240px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: flex-start;
|
||||
|
||||
.CenterChart1itemTXT {
|
||||
user-select: none;
|
||||
padding: 8px 0;
|
||||
font-size: 18px;
|
||||
font-weight: 400;
|
||||
letter-spacing: 1px;
|
||||
color: rgba(255, 255, 255, 0.9);
|
||||
text-align: center;
|
||||
}
|
||||
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;
|
||||
|
||||
.TableContainer {
|
||||
flex: 1;
|
||||
}
|
||||
.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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -82,7 +82,7 @@ function VideoContainer(props) {
|
||||
};
|
||||
|
||||
function handleEnterVideoEnd() {
|
||||
// console.log('video end');
|
||||
console.log('video end');
|
||||
enterToFloorOne();
|
||||
}
|
||||
|
||||
|
@ -1,65 +1,125 @@
|
||||
import { useState } from "react";
|
||||
import cls from "./index.module.css";
|
||||
import Chart2 from "../../../Common/TimeFireDir";
|
||||
import VideoContainer from "./VideoContainer";
|
||||
import { useState } from 'react';
|
||||
import cls from './index.module.css';
|
||||
import Chart2 from '../../../Common/TimeFireDir';
|
||||
import VideoContainer from './VideoContainer';
|
||||
|
||||
function KilnCenter() {
|
||||
const [floor, setFloor] = useState(0);
|
||||
const [floor, setFloor] = useState(0);
|
||||
|
||||
function onFloorUpdate(flr) {
|
||||
setFloor(flr);
|
||||
}
|
||||
function onFloorUpdate(flr) {
|
||||
setFloor(flr);
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
className="bgKilnInner"
|
||||
style={{
|
||||
width: "100%",
|
||||
position: "absolute",
|
||||
top: "12%",
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
}}
|
||||
>
|
||||
{/* 时间火向数据 */}
|
||||
<div
|
||||
className="fireAndTime"
|
||||
style={{ position: "absolute", top: "-112px", height: "212px" }}
|
||||
>
|
||||
<Chart2 />
|
||||
</div>
|
||||
return (
|
||||
<div
|
||||
className="bgKilnInner"
|
||||
style={{
|
||||
width: '100%',
|
||||
position: 'absolute',
|
||||
top: '12%',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
}}
|
||||
>
|
||||
{/* 时间火向数据 */}
|
||||
<div
|
||||
className="fireAndTime"
|
||||
style={{ position: 'absolute', top: '-112px', height: '212px' }}
|
||||
>
|
||||
<Chart2 />
|
||||
</div>
|
||||
|
||||
{/* menu */}
|
||||
<div
|
||||
className="subMenu"
|
||||
style={{
|
||||
display: "flex",
|
||||
marginBottom: "24px",
|
||||
justifyContent: "center",
|
||||
}}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
"flr flr1 " + cls.menuItem + " " + (floor == 1 ? cls.active : "")
|
||||
}
|
||||
onClick={() => onFloorUpdate(1)}
|
||||
>
|
||||
碹顶
|
||||
</div>
|
||||
<div
|
||||
className={
|
||||
"flr flr2 " + cls.menuItem + " " + (floor == 2 ? cls.active : "")
|
||||
}
|
||||
onClick={() => onFloorUpdate(2)}
|
||||
>
|
||||
池底
|
||||
</div>
|
||||
</div>
|
||||
{/* menu */}
|
||||
<div
|
||||
className="subMenu"
|
||||
style={{
|
||||
display: 'flex',
|
||||
marginBottom: '24px',
|
||||
justifyContent: 'center',
|
||||
}}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'flr flr1 ' + cls.menuItem + ' ' + (floor == 1 ? cls.active : '')
|
||||
}
|
||||
onClick={() => onFloorUpdate(1)}
|
||||
>
|
||||
一层
|
||||
</div>
|
||||
<div
|
||||
className={
|
||||
'flr flr2 ' + cls.menuItem + ' ' + (floor == 2 ? cls.active : '')
|
||||
}
|
||||
onClick={() => onFloorUpdate(2)}
|
||||
>
|
||||
二层
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* video */}
|
||||
<VideoContainer onFloorUpdate={onFloorUpdate} floor={floor} />
|
||||
</div>
|
||||
);
|
||||
{/* video */}
|
||||
<VideoContainer onFloorUpdate={onFloorUpdate} floor={floor} />
|
||||
|
||||
{/* <div className={cls.videoLayer2}></div> */}
|
||||
|
||||
{/* left side */}
|
||||
{/* <div
|
||||
className="leftSide"
|
||||
style={{
|
||||
position: 'absolute',
|
||||
left: '88px',
|
||||
top: '24%',
|
||||
display: 'grid',
|
||||
gridTemplateColumns: '100px 100px',
|
||||
gap: '20px 18px',
|
||||
gridAutoRows: '64px',
|
||||
}}
|
||||
>
|
||||
{data.map((item) => (
|
||||
<div
|
||||
className="leftSideItem"
|
||||
style={{
|
||||
background: '#fff3',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
background: '#32535d',
|
||||
}}
|
||||
>
|
||||
<span style={{ fontSize: '18px', lineHeight: 1, color: '#2EE4E6' }}>
|
||||
{item.name}
|
||||
</span>
|
||||
<span
|
||||
style={{ fontSize: '24px', lineHeight: '32px', color: '#fff' }}
|
||||
>
|
||||
{item.value} ℃
|
||||
</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div
|
||||
className="toolbox"
|
||||
style={{
|
||||
position: 'absolute',
|
||||
bottom: '32px',
|
||||
left: '64px',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
gap: '24px',
|
||||
}}
|
||||
>
|
||||
<div
|
||||
className="tlj tlj1"
|
||||
style={{ background: '#ccc', width: '200px', height: '100px' }}
|
||||
></div>
|
||||
<div
|
||||
className="tlj tlj2"
|
||||
style={{ background: '#ccc', width: '200px', height: '100px' }}
|
||||
></div>
|
||||
</div> */}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default KilnCenter;
|
||||
|
@ -1,14 +1,14 @@
|
||||
import { motion, AnimatePresence } from "framer-motion";
|
||||
import { useRef, useEffect, useMemo, useCallback, useState } from "react";
|
||||
import FeederStatus from "../../../../Common/Feeder";
|
||||
import TemperatureBottom from "../../../../Common/TemperatureBottom";
|
||||
import TemperatureTop from "../../../../Common/TemperatureTop";
|
||||
import { useSelector, useDispatch } from "react-redux";
|
||||
import cls from "../index.module.css";
|
||||
// import SocketContext from '../../../../../store/socket-data-provider';
|
||||
import { useContext } from "react";
|
||||
|
||||
function EnterToFloorOne(props) {
|
||||
const fireInfo = useSelector((state) => state.fireInfo);
|
||||
const fireDir = fireInfo?.fireDirection || null;
|
||||
// const ctx = useContext(SocketContext);
|
||||
const ctx = null;
|
||||
|
||||
const fireDir = ctx?.runState?.fireDirection || null;
|
||||
const [fireCanPlay, setFireCanPlay] = useState(false);
|
||||
const vd = useRef(null);
|
||||
const show = props.opacity || 0;
|
||||
@ -17,12 +17,12 @@ function EnterToFloorOne(props) {
|
||||
if (show) {
|
||||
vd.current.play();
|
||||
setTimeout(() => {
|
||||
// console.log("开启enter的火播放");
|
||||
console.log("开启enter的火播放");
|
||||
setFireCanPlay(true);
|
||||
}, 5000);
|
||||
}
|
||||
return () => {
|
||||
// console.log("关闭enter的火播放");
|
||||
console.log("关闭enter的火播放");
|
||||
setFireCanPlay(false);
|
||||
};
|
||||
}, [show]);
|
||||
@ -49,7 +49,7 @@ function EnterToFloorOne(props) {
|
||||
<source src="/video/floor1.webm" type="video/mp4" />
|
||||
</video>
|
||||
|
||||
{/* {fireCanPlay && fireDir == "东火" && (
|
||||
{fireCanPlay && fireDir == "东火" && (
|
||||
<video
|
||||
src="/video/fire_top.webm"
|
||||
muted
|
||||
@ -68,17 +68,21 @@ function EnterToFloorOne(props) {
|
||||
width={3900}
|
||||
style={{ position: "absolute", top: "-20px", left: "-20px" }}
|
||||
></video>
|
||||
)} */}
|
||||
)}
|
||||
|
||||
<TemperatureTop
|
||||
<motion.div
|
||||
className={cls.videoLayer1}
|
||||
key="eto1div"
|
||||
style={{
|
||||
top: "218px",
|
||||
left: "678px",
|
||||
top: "336px",
|
||||
left: "730px",
|
||||
width: "2380px",
|
||||
zIndex: 0,
|
||||
}}
|
||||
/>
|
||||
<FeederStatus />
|
||||
animate={{
|
||||
opacity: [0, 0, 0, 0.6, 1],
|
||||
transition: { duration: 0.3, delay: 2 },
|
||||
}}
|
||||
></motion.div>
|
||||
</motion.div>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
|
@ -1,14 +1,15 @@
|
||||
import { motion, AnimatePresence } from "framer-motion";
|
||||
import { useRef, useEffect, useMemo, useState } from "react";
|
||||
import FeederStatus from "../../../../Common/Feeder";
|
||||
import TemperatureTop from "../../../../../components/Common/TemperatureTop";
|
||||
import TemperatureBottom from "../../../../Common/TemperatureBottom";
|
||||
import { useSelector, useDispatch } from "react-redux";
|
||||
import cls from "../index.module.css";
|
||||
// import SocketContext from '../../../../../store/socket-data-provider';
|
||||
import { useContext } from "react";
|
||||
|
||||
function FloorOneToTwo(props) {
|
||||
const fireInfo = useSelector((state) => state.fireInfo);
|
||||
const fireDir = fireInfo?.fireDirection || null;
|
||||
// const ctx = useContext(SocketContext);
|
||||
|
||||
const ctx = null;
|
||||
|
||||
const fireDir = ctx?.runState?.fireDirection || null;
|
||||
const [fireCanPlay, setFireCanPlay] = useState(false);
|
||||
|
||||
const vd = useRef(null);
|
||||
@ -18,13 +19,13 @@ function FloorOneToTwo(props) {
|
||||
if (show) {
|
||||
vd.current.play();
|
||||
setTimeout(() => {
|
||||
// console.log("开启1-2的火播放");
|
||||
console.log("开启1-2的火播放");
|
||||
setFireCanPlay(true);
|
||||
}, 3000);
|
||||
}
|
||||
if (!show) setFireCanPlay(false);
|
||||
return () => {
|
||||
// console.log("关闭1-2的火播放");
|
||||
console.log("关闭1-2的火播放");
|
||||
setFireCanPlay(false);
|
||||
};
|
||||
}, [show]);
|
||||
@ -36,8 +37,8 @@ function FloorOneToTwo(props) {
|
||||
className="video-wrapper"
|
||||
style={{
|
||||
position: "fixed",
|
||||
top: "0px",
|
||||
left: "0px",
|
||||
top: "7px",
|
||||
left: "50px",
|
||||
width: "calc(100% - 50px)",
|
||||
height: "calc(100% - 7px)",
|
||||
zIndex: -998,
|
||||
@ -58,7 +59,7 @@ function FloorOneToTwo(props) {
|
||||
autoPlay
|
||||
loop
|
||||
width={3700}
|
||||
style={{ position: "absolute", top: "18px", left: "72px" }}
|
||||
style={{ position: "absolute", top: "18px", left: "56px" }}
|
||||
></video>
|
||||
)}
|
||||
{fireCanPlay && fireDir == "西火" && (
|
||||
@ -73,16 +74,20 @@ function FloorOneToTwo(props) {
|
||||
></video>
|
||||
)}
|
||||
|
||||
<TemperatureBottom
|
||||
<motion.div
|
||||
className={cls.videoLayer2}
|
||||
key="1to2div"
|
||||
style={{
|
||||
top: "208px",
|
||||
// left: "638px",
|
||||
left: "690px",
|
||||
width: "2380px",
|
||||
zIndex: 0,
|
||||
top: "360px",
|
||||
left: "740px",
|
||||
width: "2415px",
|
||||
height: "690px",
|
||||
}}
|
||||
/>
|
||||
<FeederStatus />
|
||||
animate={{
|
||||
opacity: [0, 0, 0, 0.6, 1],
|
||||
transition: { duration: 0.3, delay: 2 },
|
||||
}}
|
||||
></motion.div>
|
||||
</motion.div>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user