Compare commits
	
		
			118 Commits
		
	
	
		
			testing-re
			...
			bace9fa501
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| bace9fa501 | |||
| c6cd097433 | |||
| 4d7af62305 | |||
| 214e9fe892 | |||
| 9968280724 | |||
| 
						 | 
					8b4322996e | ||
| 
						 | 
					b325c3fc05 | ||
| 
						 | 
					28c9c1906e | ||
| 
						 | 
					7ddae1b3a4 | ||
| 
						 | 
					61477cdd30 | ||
| 
						 | 
					6e5badf01a | ||
| 311cdfc5f7 | |||
| 
						 | 
					bc8b68e449 | ||
| 
						 | 
					024f4bcf14 | ||
| 
						 | 
					361aedd4ad | ||
| 
						 | 
					60c6fdda79 | ||
| 
						 | 
					15708c0eef | ||
| 
						 | 
					2996c061dc | ||
| 
						 | 
					9894aeca50 | ||
| 
						 | 
					9f7652d9f3 | ||
| 
						 | 
					e854b966dc | ||
| 
						 | 
					dff017a5a2 | ||
| 
						 | 
					e796a07e66 | ||
| 
						 | 
					43635ff398 | ||
| 
						 | 
					19ea3287ae | ||
| 
						 | 
					4f6e4cbcf8 | ||
| 
						 | 
					c9ccc6ebcb | ||
| 
						 | 
					4374260acd | ||
| 
						 | 
					6cf533e718 | ||
| 
						 | 
					b0e7a7ca34 | ||
| 
						 | 
					0b48f68078 | ||
| 
						 | 
					c767a7fe2e | ||
| 
						 | 
					97409d61a9 | ||
| 
						 | 
					0da9ba434d | ||
| 
						 | 
					0bd1f8dcac | ||
| 
						 | 
					6e10a5aacd | ||
| 
						 | 
					2fb3d05f8c | ||
| 
						 | 
					b27a20f3cf | ||
| 
						 | 
					be5fbe1c01 | ||
| 
						 | 
					d6f9744ded | ||
| 
						 | 
					1ebda5cf6f | ||
| 
						 | 
					b7b2ad2ee5 | ||
| 
						 | 
					446234c2aa | ||
| 
						 | 
					909bd92ee6 | ||
| 
						 | 
					b16ee86def | ||
| 
						 | 
					c8d392ce51 | ||
| 
						 | 
					d1212c8729 | ||
| 
						 | 
					9d3c877628 | ||
| 
						 | 
					e1e73b341d | ||
| 
						 | 
					ac772e2caf | ||
| 
						 | 
					0b1d3aa4b3 | ||
| 
						 | 
					bee1aedda4 | ||
| 
						 | 
					678c1b86ed | ||
| 
						 | 
					0f56538c27 | ||
| 
						 | 
					6b838ce089 | ||
| 
						 | 
					e40e897882 | ||
| 
						 | 
					15d05c26d8 | ||
| 
						 | 
					c9829d4f5a | ||
| 
						 | 
					a32e6fb591 | ||
| 
						 | 
					4b043214ca | ||
| 
						 | 
					871efd2eb2 | ||
| 
						 | 
					0cd25a6972 | ||
| 
						 | 
					a73d61fad8 | ||
| 
						 | 
					3f44cb9e9a | ||
| 
						 | 
					060616e845 | ||
| 
						 | 
					2722ca6122 | ||
| 
						 | 
					049a0804ac | ||
| 
						 | 
					4e73410495 | ||
| 
						 | 
					c2802627d6 | ||
| 
						 | 
					b57b65ffd4 | ||
| 
						 | 
					b35cf01fc8 | ||
| 
						 | 
					f6cbc3a34a | ||
| 
						 | 
					373f990517 | ||
| 
						 | 
					94a713a803 | ||
| 
						 | 
					903a576cdc | ||
| 
						 | 
					4fc0cf19e9 | ||
| 6374fcdb6f | |||
| 
						 | 
					31e065fa5a | ||
| 98ad9f590c | |||
| 682cfc0407 | |||
| f32306096f | |||
| 
						 | 
					a2349e6f26 | ||
| 
						 | 
					5107dd8ce8 | ||
| 
						 | 
					0b91868b4f | ||
| 
						 | 
					bb541962dd | ||
| 
						 | 
					c3511e1bfe | ||
| 
						 | 
					e4a2af8458 | ||
| 
						 | 
					68065b612a | ||
| 
						 | 
					ac711e6f2a | ||
| 
						 | 
					19825dcb5f | ||
| 
						 | 
					cb0de3b5d0 | ||
| 
						 | 
					85ed13d8f5 | ||
| 
						 | 
					aa2a730acc | ||
| 
						 | 
					c549f38231 | ||
| 
						 | 
					9f51f2b3cb | ||
| 
						 | 
					d4a4e82aa6 | ||
| 
						 | 
					dd5ce4d90d | ||
| 
						 | 
					eadbfcb982 | ||
| 
						 | 
					42e5bea184 | ||
| 
						 | 
					5f92580c7e | ||
| 9a4f60a75a | |||
| 9814c2b6e9 | |||
| 
						 | 
					49ac95fbbd | ||
| 
						 | 
					6eb4102863 | ||
| 
						 | 
					ad305f0c46 | ||
| 
						 | 
					4a882104c8 | ||
| 
						 | 
					ca6a1c6ede | ||
| 
						 | 
					52f028d806 | ||
| 
						 | 
					69dcea7909 | ||
| 
						 | 
					04a15dc14c | ||
| 
						 | 
					b601e9065a | ||
| 
						 | 
					550da629c0 | ||
| 
						 | 
					d1d47cf5ac | ||
| 
						 | 
					a880f62393 | ||
| 
						 | 
					d65fc0e3ed | ||
| 
						 | 
					af531456f4 | ||
| 
						 | 
					bc03a717bb | ||
| 
						 | 
					3821121a6f | 
							
								
								
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						@@ -1,7 +1,7 @@
 | 
			
		||||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
 | 
			
		||||
 | 
			
		||||
# dependencies
 | 
			
		||||
/node_modules
 | 
			
		||||
**/node_modules
 | 
			
		||||
/.pnp
 | 
			
		||||
.pnp.js
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										12377
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
							
								
								
									
										11
									
								
								package.json
									
									
									
									
									
								
							
							
						
						@@ -3,6 +3,7 @@
 | 
			
		||||
  "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",
 | 
			
		||||
@@ -22,6 +23,7 @@
 | 
			
		||||
    "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",
 | 
			
		||||
@@ -59,6 +61,7 @@
 | 
			
		||||
    "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",
 | 
			
		||||
@@ -67,7 +70,9 @@
 | 
			
		||||
  "scripts": {
 | 
			
		||||
    "start": "node scripts/start.js",
 | 
			
		||||
    "build": "node scripts/build.js",
 | 
			
		||||
    "test": "node scripts/test.js"
 | 
			
		||||
    "server": "node websocket/server.js",
 | 
			
		||||
    "test": "node scripts/test.js",
 | 
			
		||||
    "ws": "node websocket/server.js"
 | 
			
		||||
  },
 | 
			
		||||
  "eslintConfig": {
 | 
			
		||||
    "extends": [
 | 
			
		||||
@@ -89,8 +94,10 @@
 | 
			
		||||
  },
 | 
			
		||||
  "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"
 | 
			
		||||
    "less-loader": "^11.1.3",
 | 
			
		||||
    "typescript": "^5.3.3"
 | 
			
		||||
  },
 | 
			
		||||
  "jest": {
 | 
			
		||||
    "roots": [
 | 
			
		||||
 
 | 
			
		||||
@@ -29,6 +29,8 @@
 | 
			
		||||
  <body>
 | 
			
		||||
    <noscript>You need to enable JavaScript to run this app.</noscript>
 | 
			
		||||
    <div id="root"></div>
 | 
			
		||||
    <!-- <div id="alarm-list-container"></div> -->
 | 
			
		||||
 | 
			
		||||
    <!--
 | 
			
		||||
      This HTML file is a template.
 | 
			
		||||
      If you open it directly in the browser, you will see an empty page.
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								public/video/1to2_old.webm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										
											BIN
										
									
								
								public/video/2to1_old.webm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										
											BIN
										
									
								
								public/video/east_fire.webm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										
											BIN
										
									
								
								public/video/enter_old.webm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										
											BIN
										
									
								
								public/video/floor1_old.webm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										
											BIN
										
									
								
								public/video/west_fire.webm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										53
									
								
								src/App.js
									
									
									
									
									
								
							
							
						
						@@ -1,27 +1,68 @@
 | 
			
		||||
// 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 { useState } from "react";
 | 
			
		||||
import { useEffect, 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 = ["窑炉总览", "窑炉内部", "窑炉优化","退火监测", "质检统计", "能耗分析"];
 | 
			
		||||
const LUNBO_INTERVAL = 60 * 1000;
 | 
			
		||||
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]);
 | 
			
		||||
      }, LUNBO_INTERVAL);
 | 
			
		||||
    }
 | 
			
		||||
    return () => {
 | 
			
		||||
      clearInterval(timer);
 | 
			
		||||
    };
 | 
			
		||||
  }, [lunbo, navActive]);
 | 
			
		||||
 | 
			
		||||
  function handleSwitchChange(val) {
 | 
			
		||||
    setlunbo(val);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function handleMenuChange(value) {
 | 
			
		||||
    setNavActive(value);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    <>
 | 
			
		||||
      <div id="FullScreen" style={styles}>
 | 
			
		||||
        <NavMenu active={navActive} onChangeActive={(v) => setNavActive(v)} />
 | 
			
		||||
      <div id="FullScreen" style={{ ...styles, overflow: "hidden" }}>
 | 
			
		||||
        <NavMenu active={navActive} onChangeActive={handleMenuChange} />
 | 
			
		||||
        <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} />
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								src/assets/Icon/dontknowwhatitis.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 5.9 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/assets/Icon/kilnBottom.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 4.1 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/assets/Icon/kilnPress.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 4.1 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/assets/Icon/kilnTop.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 4.0 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/assets/Icon/lightnen.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 7.7 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/assets/Icon/liquidTrend.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 4.1 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/assets/Icon/oilstation.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 5.3 KiB  | 
							
								
								
									
										14
									
								
								src/assets/Icon/temp.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,14 @@
 | 
			
		||||
<?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>
 | 
			
		||||
| 
		 After Width: | Height: | Size: 2.0 KiB  | 
							
								
								
									
										14
									
								
								src/assets/Icon/triangle.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,14 @@
 | 
			
		||||
<?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>
 | 
			
		||||
| 
		 After Width: | Height: | Size: 1.4 KiB  | 
| 
		 Before Width: | Height: | Size: 2.7 MiB After Width: | Height: | Size: 7.5 MiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/assets/kilnSpeed.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 51 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/assets/offline.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 13 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/assets/online.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 13 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/assets/tempIntr.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 22 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/assets/warn-bg.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 2.0 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/assets/warn-icon.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 2.2 KiB  | 
							
								
								
									
										5
									
								
								src/components/Common/AmenSelector/index.jsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,5 @@
 | 
			
		||||
function AmenSelector() {
 | 
			
		||||
  return <div className="amen-selector"></div>;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default AmenSelector;
 | 
			
		||||
							
								
								
									
										213
									
								
								src/components/Common/AnnealFanRunFrequence/index.jsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,213 @@
 | 
			
		||||
// 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 {
 | 
			
		||||
    console.log('runstate changeD!......')
 | 
			
		||||
    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;
 | 
			
		||||
							
								
								
									
										52
									
								
								src/components/Common/AnnealFanRunFrequence/index.module.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,52 @@
 | 
			
		||||
.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;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										28
									
								
								src/components/Common/Arrow/index.jsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,28 @@
 | 
			
		||||
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;
 | 
			
		||||
							
								
								
									
										60
									
								
								src/components/Common/Arrow/index.module.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,60 @@
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
.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);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										32
									
								
								src/components/Common/BlueRect/index.jsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,32 @@
 | 
			
		||||
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;
 | 
			
		||||
							
								
								
									
										544
									
								
								src/components/Common/BlueRect/index.module.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,544 @@
 | 
			
		||||
.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,6 +6,7 @@ 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,9 +38,10 @@
 | 
			
		||||
		.TopSideLeftTxt {
 | 
			
		||||
			margin-right: 120px;
 | 
			
		||||
			margin-top: 15px;
 | 
			
		||||
			color: rgb(255, 255, 255, 0.8);
 | 
			
		||||
			color: rgb(255, 255, 255, 0.6);
 | 
			
		||||
			font-size: 20px;
 | 
			
		||||
			font-weight: 300px;
 | 
			
		||||
			letter-spacing: 1px;
 | 
			
		||||
			line-height: 22.174976px;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
@@ -77,9 +78,9 @@
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	.TopTitleText {
 | 
			
		||||
		margin-top: 16px;
 | 
			
		||||
		margin-top: 40px;
 | 
			
		||||
		letter-spacing: 8px;
 | 
			
		||||
		font-size: 32px;
 | 
			
		||||
		font-size: 34px;
 | 
			
		||||
		color: #00fff7;
 | 
			
		||||
		text-align: center;
 | 
			
		||||
		letter-spacing: 2px;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,73 +1,153 @@
 | 
			
		||||
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";
 | 
			
		||||
 | 
			
		||||
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 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 header = ["产线名", "原板宽度", "净板宽", "玻璃厚度"];
 | 
			
		||||
function filterData(rawData) {
 | 
			
		||||
  return (rawData ?? []).map((item) => [
 | 
			
		||||
    // 产线名
 | 
			
		||||
    item.productionLine,
 | 
			
		||||
    // 原板宽度
 | 
			
		||||
    item.length,
 | 
			
		||||
    // 净板宽
 | 
			
		||||
    item.wide,
 | 
			
		||||
    // 玻璃厚度
 | 
			
		||||
    item.thick,
 | 
			
		||||
  ]);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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 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 replaceStyle(Arr, opencity) {
 | 
			
		||||
// let header = ["产线名", "原板宽度", "净板宽", "玻璃厚度"];
 | 
			
		||||
 | 
			
		||||
function replaceStyle(Arr, opacity) {
 | 
			
		||||
  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,${opencity})">${Arr[i][j]}<span/>`;
 | 
			
		||||
      temp[i][j] = `<span style="color:rgba(255, 255, 255,${opacity})">${
 | 
			
		||||
        Arr[i][j]
 | 
			
		||||
      } ${j == 0 ? "" : "mm"}<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%;
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								src/components/Common/CurrentTemp/6778.ttf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										7
									
								
								src/components/Common/CurrentTemp/font.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,7 @@
 | 
			
		||||
@font-face {
 | 
			
		||||
  font-family: "HelloFont WenYiHei";
 | 
			
		||||
  /* font-style: normal;
 | 
			
		||||
  font-weight: 400; */
 | 
			
		||||
  src: url("./ziyou.ttf");
 | 
			
		||||
  /* font-display: swap; */
 | 
			
		||||
}
 | 
			
		||||
@@ -1,138 +1,259 @@
 | 
			
		||||
import BottomBarItem from '../BottomItemBackground';
 | 
			
		||||
import GraphBase from '../GraphBase';
 | 
			
		||||
import { Radio } from 'antd';
 | 
			
		||||
import cls from './index.module.css';
 | 
			
		||||
import { useState } from 'react';
 | 
			
		||||
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";
 | 
			
		||||
 | 
			
		||||
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: '50%',
 | 
			
		||||
						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: "45%",
 | 
			
		||||
            background:
 | 
			
		||||
              "linear-gradient(to bottom, transparent, #fff3, #fffa, #fff3, transparent)",
 | 
			
		||||
          }}
 | 
			
		||||
        ></span>
 | 
			
		||||
      )}
 | 
			
		||||
      {props.children}
 | 
			
		||||
    </div>
 | 
			
		||||
  );
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
function WindFrequence(props) {
 | 
			
		||||
	const [dataSource, setDataSource] = useState('风机');
 | 
			
		||||
  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);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
	function handleSourceChange(v) {
 | 
			
		||||
		console.log('val', v);
 | 
			
		||||
	}
 | 
			
		||||
  useEffect(() => {
 | 
			
		||||
    setCurrentLineTemp(
 | 
			
		||||
      (currentTempList &&
 | 
			
		||||
        currentTempList[1 + lines.indexOf(dataSource) + "#"]) ||
 | 
			
		||||
        []
 | 
			
		||||
    );
 | 
			
		||||
  }, [dataSource, currentTempList]);
 | 
			
		||||
 | 
			
		||||
	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>
 | 
			
		||||
	);
 | 
			
		||||
  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>
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default WindFrequence;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,139 +1,141 @@
 | 
			
		||||
.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: 20px;
 | 
			
		||||
	line-height: 1;
 | 
			
		||||
	letter-spacing: 1.5px;
 | 
			
		||||
	margin: 0;
 | 
			
		||||
	padding-left: 20px;
 | 
			
		||||
	width: 50%;
 | 
			
		||||
  color: #fff;
 | 
			
		||||
  font-size: 18px;
 | 
			
		||||
  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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.areaPureValue:not(:first-child) {
 | 
			
		||||
	border-left: 2px solid #fff6;
 | 
			
		||||
span.areaPureValue:not(:first-of-type) {
 | 
			
		||||
  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: 17px;
 | 
			
		||||
	line-height: 22px;
 | 
			
		||||
	letter-spacing: 1.2px;
 | 
			
		||||
  display: inline-block;
 | 
			
		||||
  font-size: 14px;
 | 
			
		||||
  line-height: 16px;
 | 
			
		||||
  letter-spacing: 1.2px;
 | 
			
		||||
  font-family: "HelloFont WenYiHei", sans-serif;
 | 
			
		||||
  color: #53c2d4;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.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;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								src/components/Common/CurrentTemp/ziyou.ttf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										184
									
								
								src/components/Common/Energy/EnergeCostRealtime/index.jsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,184 @@
 | 
			
		||||
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?.elecQty1)?.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;
 | 
			
		||||
@@ -0,0 +1,60 @@
 | 
			
		||||
.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,128 +1,151 @@
 | 
			
		||||
import cls from './index.module.css';
 | 
			
		||||
import { randomInt } from '../../../../utils';
 | 
			
		||||
import * as echarts from 'echarts';
 | 
			
		||||
import { Switch, Radio } from 'antd';
 | 
			
		||||
import ReactECharts from 'echarts-for-react';
 | 
			
		||||
import cls from "./index.module.css";
 | 
			
		||||
import { 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";
 | 
			
		||||
 | 
			
		||||
const EnergyCostChart = (props) => {
 | 
			
		||||
	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 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");
 | 
			
		||||
 | 
			
		||||
	function handleSwitchChange(val) {
 | 
			
		||||
		// val: boolean
 | 
			
		||||
		console.log('switch change', val);
 | 
			
		||||
	}
 | 
			
		||||
  const [timestr, setTimestr] = useState(
 | 
			
		||||
    dayjs().subtract(7, "day").format("YYYY.MM.DD") +
 | 
			
		||||
      " - " +
 | 
			
		||||
      dayjs().subtract(1, "day").format("YYYY.MM.DD")
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
	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>
 | 
			
		||||
	);
 | 
			
		||||
  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>
 | 
			
		||||
  );
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export default EnergyCostChart;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,85 +1,95 @@
 | 
			
		||||
.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;
 | 
			
		||||
  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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.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;
 | 
			
		||||
  border: none !important;
 | 
			
		||||
  border-radius: 0 !important;
 | 
			
		||||
}
 | 
			
		||||
.radioGroupShort * {
 | 
			
		||||
  border: none !important;
 | 
			
		||||
  border-radius: 6px !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,33 +1,22 @@
 | 
			
		||||
import cls from './index.module.scss';
 | 
			
		||||
import Container from '../../Container';
 | 
			
		||||
import TechSplitline from '../TechSplitline';
 | 
			
		||||
import EnergyCostChart from './EnergyCostChart';
 | 
			
		||||
import cls from "./index.module.scss";
 | 
			
		||||
import Container from "../../Container";
 | 
			
		||||
import TechSplitline from "../TechSplitline";
 | 
			
		||||
import EnergyCostChart from "./EnergyCostChart";
 | 
			
		||||
import EnergyCostRealtime from "./EnergeCostRealtime";
 | 
			
		||||
 | 
			
		||||
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>
 | 
			
		||||
 | 
			
		||||
				<TechSplitline />
 | 
			
		||||
  return (
 | 
			
		||||
    <Container title="能耗" icon="battery" className={cls.energyCost}>
 | 
			
		||||
      <div className={`flex flex-col`}>
 | 
			
		||||
        <EnergyCostRealtime />
 | 
			
		||||
 | 
			
		||||
				<EnergyCostChart />
 | 
			
		||||
			</div>
 | 
			
		||||
		</Container>
 | 
			
		||||
	);
 | 
			
		||||
        <TechSplitline />
 | 
			
		||||
 | 
			
		||||
        <EnergyCostChart />
 | 
			
		||||
      </div>
 | 
			
		||||
    </Container>
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default EnergyCost;
 | 
			
		||||
 
 | 
			
		||||
@@ -2,7 +2,7 @@
 | 
			
		||||
	background: url(../../../assets/energy.png) no-repeat;
 | 
			
		||||
	background-size: 100% 100%;
 | 
			
		||||
	width: 626px;
 | 
			
		||||
	height: 400px;
 | 
			
		||||
	height: 460px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.cost__info {
 | 
			
		||||
@@ -18,12 +18,9 @@
 | 
			
		||||
	border-radius: 2px;
 | 
			
		||||
	color: hsl(0, 0%, 100%, 0.9);
 | 
			
		||||
	box-shadow: inset 0 0 17px 0px hsla(0, 0%, 100%, 0.15);
 | 
			
		||||
	// width: 288px;
 | 
			
		||||
	height: 43px;
 | 
			
		||||
	font-size: 20px;
 | 
			
		||||
	letter-spacing: 1.43px;
 | 
			
		||||
	font-size: 14px;
 | 
			
		||||
	line-height: 40px;
 | 
			
		||||
	text-align: center;
 | 
			
		||||
	padding-left: 12px;
 | 
			
		||||
	user-select: none;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,46 +1,20 @@
 | 
			
		||||
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" : "#a81b2655"
 | 
			
		||||
                item == 1 ? "#2760ff55" : item == 0 ? "#a81b2655" : "#E6A23C55"
 | 
			
		||||
              }; margin-right: 8px; width: 8px; height: 8px; border-radius: 8px; background: ${
 | 
			
		||||
          item == 1 ? "#2760ff" : "#a81b26"
 | 
			
		||||
        }"></span><span style="color: ${item == 1 ? "#2760ff" : "#a81b26"}">${
 | 
			
		||||
          item == 1 ? "正常" : "故障"
 | 
			
		||||
        }</span></div>`;
 | 
			
		||||
          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>`;
 | 
			
		||||
    });
 | 
			
		||||
@@ -49,7 +23,17 @@ function attachStyle(data) {
 | 
			
		||||
 | 
			
		||||
function FanInfo(props) {
 | 
			
		||||
  const rowNum = props.rows || 8;
 | 
			
		||||
  let data = getRandomRows(100);
 | 
			
		||||
  // 默认使用风机信息,可以使用 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 config = {
 | 
			
		||||
    headerBGC: "rgba(4, 44, 76, 0.3)",
 | 
			
		||||
@@ -60,11 +44,10 @@ function FanInfo(props) {
 | 
			
		||||
    ],
 | 
			
		||||
    oddRowBGC: "#042444",
 | 
			
		||||
    evenRowBGC: "#042c4c",
 | 
			
		||||
    columnWidth: [70, 96],
 | 
			
		||||
    // columnWidth: data.length > 12 ? [50, 136] : [88, 256],
 | 
			
		||||
    columnWidth: [50, 136],
 | 
			
		||||
    rowNum,
 | 
			
		||||
    // headerHeight: 40,
 | 
			
		||||
    hoverPause: false,
 | 
			
		||||
    // data: replaceStyle(data, 0.7),
 | 
			
		||||
    hoverPause: true,
 | 
			
		||||
    data: attachStyle(data),
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
@@ -78,7 +61,9 @@ function FanInfo(props) {
 | 
			
		||||
        className="flex"
 | 
			
		||||
        style={{
 | 
			
		||||
          display: "flex",
 | 
			
		||||
          flex: 1,
 | 
			
		||||
          gap: "20px",
 | 
			
		||||
          // gap: data.length > 12 ? "20px" : 0,
 | 
			
		||||
          height: "100%",
 | 
			
		||||
          position: "relative",
 | 
			
		||||
        }}
 | 
			
		||||
@@ -86,9 +71,15 @@ function FanInfo(props) {
 | 
			
		||||
        <div className="flex-1" style={{ flex: 1 }}>
 | 
			
		||||
          <ScrollBoard
 | 
			
		||||
            config={config}
 | 
			
		||||
            style={{ width: "280px", height: "100%" }}
 | 
			
		||||
            style={{
 | 
			
		||||
              width: "280px",
 | 
			
		||||
              // width: data.length > 12 ? "280px" : "100%",
 | 
			
		||||
              height: "100%",
 | 
			
		||||
            }}
 | 
			
		||||
          />
 | 
			
		||||
        </div>
 | 
			
		||||
        {/* {data.length > 12 && (
 | 
			
		||||
          <> */}
 | 
			
		||||
        <div
 | 
			
		||||
          className="verticalLine"
 | 
			
		||||
          style={{
 | 
			
		||||
@@ -103,10 +94,12 @@ function FanInfo(props) {
 | 
			
		||||
        ></div>
 | 
			
		||||
        <div className="flex-1" style={{ flex: 1 }}>
 | 
			
		||||
          <ScrollBoard
 | 
			
		||||
            config={config}
 | 
			
		||||
            config={{ ...config, data: attachStyle(dataRight) }}
 | 
			
		||||
            style={{ width: "280px", height: "100%" }}
 | 
			
		||||
          />
 | 
			
		||||
        </div>
 | 
			
		||||
        {/* </>
 | 
			
		||||
        )} */}
 | 
			
		||||
      </div>
 | 
			
		||||
    </GraphBase>
 | 
			
		||||
  );
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										248
									
								
								src/components/Common/FanInfoStretch/index.jsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,248 @@
 | 
			
		||||
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;
 | 
			
		||||
							
								
								
									
										50
									
								
								src/components/Common/FanInfoStretch/index.module.scss
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,50 @@
 | 
			
		||||
.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,20 +1,71 @@
 | 
			
		||||
// 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, useContext } from "react";
 | 
			
		||||
// import SocketContext from '../../../store/socket-data-provider';
 | 
			
		||||
import { useState } from "react";
 | 
			
		||||
import { useSelector } from "react-redux";
 | 
			
		||||
 | 
			
		||||
function WindFrequence(props) {
 | 
			
		||||
  const [showChart, setShowChart] = useState(true);
 | 
			
		||||
  // const { runState, hisState } = useContext(SocketContext);
 | 
			
		||||
  const [showChart, setShowChart] = useState(false);
 | 
			
		||||
  const runState = useSelector((state) => state.fanFrequence.runtime);
 | 
			
		||||
  const hisState = useSelector((state) => state.fanFrequence.history);
 | 
			
		||||
 | 
			
		||||
  const runState = null;
 | 
			
		||||
  const hisState = null;
 | 
			
		||||
  const [options, dataList] = getOptions(showChart, hisState, runState);
 | 
			
		||||
 | 
			
		||||
  let dataList = [];
 | 
			
		||||
  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 seriesData = [];
 | 
			
		||||
  const colors = [
 | 
			
		||||
    "#12FFF5",
 | 
			
		||||
@@ -29,20 +80,15 @@ function WindFrequence(props) {
 | 
			
		||||
  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));
 | 
			
		||||
    seriesData =
 | 
			
		||||
      hisState != null
 | 
			
		||||
        ? Object.keys(hisState)
 | 
			
		||||
            .sort()
 | 
			
		||||
            .map((key) => hisState[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 },
 | 
			
		||||
@@ -104,9 +150,10 @@ function WindFrequence(props) {
 | 
			
		||||
        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" },
 | 
			
		||||
            // 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" },
 | 
			
		||||
          ]),
 | 
			
		||||
        },
 | 
			
		||||
      })),
 | 
			
		||||
@@ -115,80 +162,32 @@ function WindFrequence(props) {
 | 
			
		||||
      },
 | 
			
		||||
    };
 | 
			
		||||
  } 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" },
 | 
			
		||||
          { 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" },
 | 
			
		||||
        ];
 | 
			
		||||
    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" },
 | 
			
		||||
          ];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  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>
 | 
			
		||||
  );
 | 
			
		||||
  return [options, dataList];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default WindFrequence;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,33 +1,52 @@
 | 
			
		||||
.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: 9px 0;
 | 
			
		||||
	text-align: center;
 | 
			
		||||
	color: #fff;
 | 
			
		||||
	box-shadow: inset 0 0 16px 4px rgba(255, 255, 255, 0.197);
 | 
			
		||||
  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;
 | 
			
		||||
  position: absolute;
 | 
			
		||||
  top: 22px;
 | 
			
		||||
  right: 24px;
 | 
			
		||||
  height: 32px;
 | 
			
		||||
  width: 410px;
 | 
			
		||||
  display: flex;
 | 
			
		||||
  align-items: center;
 | 
			
		||||
  justify-content: flex-start;
 | 
			
		||||
  color: #fff;
 | 
			
		||||
}
 | 
			
		||||
.relative {
 | 
			
		||||
	position: relative;
 | 
			
		||||
  position: relative;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.flex {
 | 
			
		||||
  display: flex;
 | 
			
		||||
  align-items: center;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.fanName {
 | 
			
		||||
  text-align: right;
 | 
			
		||||
  flex: 7;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.fanValue {
 | 
			
		||||
  flex: 3;
 | 
			
		||||
  text-align: left;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										16
									
								
								src/components/Common/Feeder/feeder.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,16 @@
 | 
			
		||||
.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%;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										104
									
								
								src/components/Common/Feeder/index.jsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,104 @@
 | 
			
		||||
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,187 +1,223 @@
 | 
			
		||||
// 助燃风流量
 | 
			
		||||
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';
 | 
			
		||||
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";
 | 
			
		||||
 | 
			
		||||
/** 助燃风流量 */
 | 
			
		||||
function GasI(props) {
 | 
			
		||||
	const [showChart, setShowChart] = useState(true);
 | 
			
		||||
	// const { runState, hisState } = useContext(SocketContext);
 | 
			
		||||
  const [showChart, setShowChart] = useState(true);
 | 
			
		||||
  const runState = useSelector((state) => state.combustionAir.runtime);
 | 
			
		||||
  const hisState = useSelector((state) => state.combustionAir.history);
 | 
			
		||||
 | 
			
		||||
	const runState = null;
 | 
			
		||||
	const hisState = null;
 | 
			
		||||
  let [options, dataList] = getOptions(showChart, hisState, runState);
 | 
			
		||||
 | 
			
		||||
	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));
 | 
			
		||||
  function handleSwitchChange(val) {
 | 
			
		||||
    if (val) {
 | 
			
		||||
      setShowChart(true);
 | 
			
		||||
    } else {
 | 
			
		||||
      setShowChart(false);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
		// 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);
 | 
			
		||||
	}
 | 
			
		||||
  const desc =
 | 
			
		||||
    dayjs().subtract(7, "day").format("YYYY.MM.DD") +
 | 
			
		||||
    " - " +
 | 
			
		||||
    dayjs().subtract(1, "day").format("YYYY.MM.DD");
 | 
			
		||||
 | 
			
		||||
	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>
 | 
			
		||||
  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>
 | 
			
		||||
 | 
			
		||||
			<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>
 | 
			
		||||
	);
 | 
			
		||||
      <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>
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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,9 +26,10 @@
 | 
			
		||||
	position: absolute;
 | 
			
		||||
	/* background: #00ee33; */
 | 
			
		||||
	top: 20px;
 | 
			
		||||
	left: 180px;
 | 
			
		||||
	right: 24px;
 | 
			
		||||
	height: 32px;
 | 
			
		||||
	width: 190px;
 | 
			
		||||
	width: 128px;
 | 
			
		||||
	text-align: right;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -62,7 +63,21 @@
 | 
			
		||||
	padding: 12px 0;
 | 
			
		||||
	text-align: center;
 | 
			
		||||
	color: #fff;
 | 
			
		||||
	box-shadow: inset 0 0 16px 4px rgba(255, 255, 255, 0.197);
 | 
			
		||||
	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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.headWidget {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,124 +1,139 @@
 | 
			
		||||
// TODO: 通用组件 - 按钮 菜单控制层
 | 
			
		||||
import useIcon from '../../../hooks/useIcon';
 | 
			
		||||
import cls from './index.module.css';
 | 
			
		||||
import { useMemo, useState } from 'react';
 | 
			
		||||
import { Switch, Radio } from 'antd';
 | 
			
		||||
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";
 | 
			
		||||
 | 
			
		||||
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,
 | 
			
		||||
		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,
 | 
			
		||||
    defaultSelect,
 | 
			
		||||
    selectWidth,
 | 
			
		||||
    legend,
 | 
			
		||||
  } = props;
 | 
			
		||||
  const descSmall = props.descSmall || false;
 | 
			
		||||
  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 (dateOptions) {
 | 
			
		||||
		dto = dateOptions.map((item) => (
 | 
			
		||||
			<Radio.Button value={item} key={item} className="radio-group__item">
 | 
			
		||||
				{item}
 | 
			
		||||
			</Radio.Button>
 | 
			
		||||
		));
 | 
			
		||||
	}
 | 
			
		||||
  if (props.switchPosition) {
 | 
			
		||||
    props.switchPosition.forEach((item, index) => {
 | 
			
		||||
      if (item != null) {
 | 
			
		||||
        switchStyle[index == 0 ? "top" : "left"] = item + "px";
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
	function handleSwitchChange(v) {
 | 
			
		||||
		v ? setShowChart(true) : setShowChart(false);
 | 
			
		||||
		onSwitch(v);
 | 
			
		||||
	}
 | 
			
		||||
  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: "calc(14px * var(--scale))",
 | 
			
		||||
              lineHeight: 1,
 | 
			
		||||
              paddingLeft: "calc(12px * var(--scale))",
 | 
			
		||||
            }}
 | 
			
		||||
          >
 | 
			
		||||
            - 无 -
 | 
			
		||||
          </span>
 | 
			
		||||
        }
 | 
			
		||||
        onChange={(value, option) => onDateChange(value)}
 | 
			
		||||
      />
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
	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>
 | 
			
		||||
	);
 | 
			
		||||
  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} ${descSmall ? cls.graphBaseDescSmall : ''}`}>{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>
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default GraphBase;
 | 
			
		||||
 
 | 
			
		||||
@@ -63,7 +63,7 @@
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.graphBaseTitle > img {
 | 
			
		||||
	width: 20px;
 | 
			
		||||
	width: 24px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.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: 20px;
 | 
			
		||||
	font-size: 22px;
 | 
			
		||||
	color: #fff;
 | 
			
		||||
	letter-spacing: 2px;
 | 
			
		||||
	font-weight: 500;
 | 
			
		||||
@@ -85,13 +85,19 @@
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.graphBaseDesc {
 | 
			
		||||
	position: absolute;
 | 
			
		||||
	margin-left: 8px;
 | 
			
		||||
	/* position: absolute;
 | 
			
		||||
	top: 25px;
 | 
			
		||||
	left: 150px;
 | 
			
		||||
	left: 150px; */
 | 
			
		||||
	font-size: 19px;
 | 
			
		||||
	color: #76fff9;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.graphBaseDescSmall {
 | 
			
		||||
	font-size: 16px;
 | 
			
		||||
	color: #76fff9;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.graphBaseSwitch {
 | 
			
		||||
	position: absolute;
 | 
			
		||||
	top: 30px;
 | 
			
		||||
@@ -114,7 +120,7 @@
 | 
			
		||||
 | 
			
		||||
.radioGroup * {
 | 
			
		||||
	border: none !important;
 | 
			
		||||
	border-radius: 0 !important;
 | 
			
		||||
	border-radius: 6px !important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.radioGroup *:focus-within {
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										38
									
								
								src/components/Common/GraphBase/selector.style.overwrite.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,38 @@
 | 
			
		||||
.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;
 | 
			
		||||
    font-size: calc(14px * var(--scale));
 | 
			
		||||
 }
 | 
			
		||||
 | 
			
		||||
.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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.xc-date-selector-menu .ant-select-item-option {
 | 
			
		||||
    /* padding: 5px 8px; */
 | 
			
		||||
    padding: .3em .35em;
 | 
			
		||||
    min-height: unset;
 | 
			
		||||
}
 | 
			
		||||
/* 
 | 
			
		||||
.ant-select-selector::after {
 | 
			
		||||
    content: '\25BC' !important;
 | 
			
		||||
    visibility: visible !important; L
 | 
			
		||||
    position: absolute;
 | 
			
		||||
    top: 2px;
 | 
			
		||||
    right: 22px;
 | 
			
		||||
    color: #04233c;
 | 
			
		||||
} */
 | 
			
		||||
@@ -1,60 +1,24 @@
 | 
			
		||||
import cls from "./kiln.module.scss";
 | 
			
		||||
import Container from "../../Container";
 | 
			
		||||
import { useEffect } from "react";
 | 
			
		||||
import { useSelector, useDispatch } from "react-redux";
 | 
			
		||||
import { useSelector } 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}>
 | 
			
		||||
            {item.label}: {item.value}
 | 
			
		||||
            <span className={cls.label}>{item.label}</span>
 | 
			
		||||
            <span className={cls.value}>{item.value}</span>
 | 
			
		||||
            {/* {item.label}: {item.value} */}
 | 
			
		||||
          </div>
 | 
			
		||||
        ))}
 | 
			
		||||
      </div>
 | 
			
		||||
 
 | 
			
		||||
@@ -24,6 +24,19 @@
 | 
			
		||||
			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,98 +1,104 @@
 | 
			
		||||
import * as echarts from 'echarts';
 | 
			
		||||
import { randomInt } from '../../../../utils';
 | 
			
		||||
import * as echarts from "echarts";
 | 
			
		||||
 | 
			
		||||
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 * 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',
 | 
			
		||||
		},
 | 
			
		||||
	};
 | 
			
		||||
  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: ''
 | 
			
		||||
    },
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,37 +1,31 @@
 | 
			
		||||
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';
 | 
			
		||||
import cls from "./index.module.css";
 | 
			
		||||
import ReactECharts from "echarts-for-react";
 | 
			
		||||
import getOptions from "./chart.config";
 | 
			
		||||
import { useSelector, useDispatch } from "react-redux";
 | 
			
		||||
 | 
			
		||||
function GasChart(props) {
 | 
			
		||||
	const { dataSource } = props;
 | 
			
		||||
	// const { hisState } = useContext(SocketContext);
 | 
			
		||||
	const hisState = null;
 | 
			
		||||
	const dataName = dataSource == 'gas-i' ? 'kilnGasT1' : 'kilnGasT2';
 | 
			
		||||
  const { dataSource } = props;
 | 
			
		||||
  const hisState = useSelector((state) => state.natGas.history);
 | 
			
		||||
  const dataName = dataSource == "gas-i" ? "gasIHistory" : "gasIIHistory";
 | 
			
		||||
 | 
			
		||||
	// 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));
 | 
			
		||||
  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));
 | 
			
		||||
 | 
			
		||||
	// 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>
 | 
			
		||||
	);
 | 
			
		||||
  return (
 | 
			
		||||
    <div className={cls.gasChart}>
 | 
			
		||||
      <ReactECharts
 | 
			
		||||
        key={dataSource}
 | 
			
		||||
        option={getOptions(
 | 
			
		||||
          seriesData,
 | 
			
		||||
          dataSource == "gas-i" ? "天然气I" : "天然气II"
 | 
			
		||||
        )}
 | 
			
		||||
        style={{ height: "100%" }}
 | 
			
		||||
      />
 | 
			
		||||
    </div>
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default GasChart;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,55 +1,58 @@
 | 
			
		||||
import cls from './index.module.css';
 | 
			
		||||
import { useContext, useEffect, useState } from 'react';
 | 
			
		||||
// import SocketContext from '../../../../store/socket-data-provider';
 | 
			
		||||
import cls from "./index.module.css";
 | 
			
		||||
import { useSelector } from "react-redux";
 | 
			
		||||
 | 
			
		||||
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 } = useContext(SocketContext);
 | 
			
		||||
	const runState = null;
 | 
			
		||||
  const runState = useSelector((state) => state.natGas.runtime);
 | 
			
		||||
 | 
			
		||||
	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}>
 | 
			
		||||
					{item.name}: {item.value}
 | 
			
		||||
				</div>
 | 
			
		||||
			))}
 | 
			
		||||
		</div>
 | 
			
		||||
	);
 | 
			
		||||
  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>
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default GridList;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,14 +1,27 @@
 | 
			
		||||
.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);
 | 
			
		||||
  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;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,71 +1,109 @@
 | 
			
		||||
// 天然气流量
 | 
			
		||||
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';
 | 
			
		||||
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";
 | 
			
		||||
 | 
			
		||||
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) {
 | 
			
		||||
		console.log('val', e.target.value);
 | 
			
		||||
		if (e.target.value == 'ii') {
 | 
			
		||||
			// 天然气II
 | 
			
		||||
			setDataSource('gas-ii');
 | 
			
		||||
		} else if (e.target.value == 'i') {
 | 
			
		||||
			// 天然气 I
 | 
			
		||||
			setDataSource('gas-i');
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
  // function handleSourceChange(e) {
 | 
			
		||||
  //   if (e.target.value == "ii") {
 | 
			
		||||
  //     // 天然气II
 | 
			
		||||
  //     setDataSource("gas-ii");
 | 
			
		||||
  //   } else if (e.target.value == "i") {
 | 
			
		||||
  //     // 天然气 I
 | 
			
		||||
  //     setDataSource("gas-i");
 | 
			
		||||
  //   }
 | 
			
		||||
  // }
 | 
			
		||||
 | 
			
		||||
	return (
 | 
			
		||||
		<BottomBarItem
 | 
			
		||||
			icon="pause"
 | 
			
		||||
			title="天然气流量"
 | 
			
		||||
			className={`${cls.gas} ${props.className}`}
 | 
			
		||||
			style={props.style}
 | 
			
		||||
		>
 | 
			
		||||
			{/* 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>
 | 
			
		||||
  function handleDateChange(value) {
 | 
			
		||||
    if (value == "天然气I") {
 | 
			
		||||
      setDataSource("gas-i");
 | 
			
		||||
    } else {
 | 
			
		||||
      setDataSource("gas-ii");
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
				<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>
 | 
			
		||||
  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>
 | 
			
		||||
 | 
			
		||||
			<div className={cls.chart}>
 | 
			
		||||
				{showChart && <GasChart dataSource={dataSource} />}
 | 
			
		||||
				{!showChart && <GridList dataSource={dataSource} />}
 | 
			
		||||
			</div>
 | 
			
		||||
		</BottomBarItem>
 | 
			
		||||
	);
 | 
			
		||||
        <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>
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default GasII;
 | 
			
		||||
 
 | 
			
		||||
@@ -24,9 +24,10 @@
 | 
			
		||||
.headWidget {
 | 
			
		||||
	position: absolute;
 | 
			
		||||
	top: 22px;
 | 
			
		||||
	right: 24px;
 | 
			
		||||
	left: 178px;
 | 
			
		||||
	height: 32px;
 | 
			
		||||
	width: 410px;
 | 
			
		||||
	width: calc(100% - 200px);
 | 
			
		||||
	/* background: #12fff5; */
 | 
			
		||||
	display: flex;
 | 
			
		||||
	align-items: center;
 | 
			
		||||
	justify-content: space-between;
 | 
			
		||||
@@ -69,7 +70,7 @@
 | 
			
		||||
 | 
			
		||||
.radioGroup * {
 | 
			
		||||
	border: none !important;
 | 
			
		||||
	border-radius: 0 !important;
 | 
			
		||||
	border-radius: 6px !important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.radioGroup *:focus-within {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,25 +1,26 @@
 | 
			
		||||
import { useCallback, useState } from 'react';
 | 
			
		||||
import cls from './index.module.scss';
 | 
			
		||||
import { useCallback, useEffect, 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"],
 | 
			
		||||
    ["窑炉优化", "/kilnOptimize"],
 | 
			
		||||
    ["退火监测", "/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,7 +1,8 @@
 | 
			
		||||
.centerMenu {
 | 
			
		||||
	position: fixed;
 | 
			
		||||
	top: 120px;
 | 
			
		||||
	left: 1340px;
 | 
			
		||||
	// left: 1340px;
 | 
			
		||||
	left: 1338px;
 | 
			
		||||
	color: white;
 | 
			
		||||
	z-index: 10000;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										24
									
								
								src/components/Common/SmokeHandle/SmokeHandleTable/index.jsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,24 @@
 | 
			
		||||
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} style={{ gridColumn: "span 2" }}>
 | 
			
		||||
        二氧化硫浓度: {(+smokeInfo?.SO2_float)?.toFixed(2) || 0}mg/m³
 | 
			
		||||
      </div>
 | 
			
		||||
      <div className={cls.info__item + " " + cls.disabled}>
 | 
			
		||||
        颗粒物浓度: {(+smokeInfo?.dust_float)?.toFixed(2) || 0}mg/m³
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
  );
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export default SmokeHandleTable;
 | 
			
		||||
@@ -1,183 +1,339 @@
 | 
			
		||||
import cls from './index.module.css';
 | 
			
		||||
import { randomInt } from '../../../../utils';
 | 
			
		||||
 | 
			
		||||
import * as echarts from 'echarts';
 | 
			
		||||
import { Switch, Radio } from 'antd';
 | 
			
		||||
import ReactECharts from 'echarts-for-react';
 | 
			
		||||
import cls from "./index.module.css";
 | 
			
		||||
import * 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";
 | 
			
		||||
 | 
			
		||||
const SmokeTrendChart = (props) => {
 | 
			
		||||
	const options = {
 | 
			
		||||
		color: ['#FFD160', '#12FFF5', '#2760FF'],
 | 
			
		||||
		grid: { top: 38, right: 12, bottom: 20, left: 48 },
 | 
			
		||||
		xAxis: {
 | 
			
		||||
			type: 'category',
 | 
			
		||||
			data: Array(7)
 | 
			
		||||
				.fill(1)
 | 
			
		||||
				.map((_, index) => {
 | 
			
		||||
					const today = new Date();
 | 
			
		||||
					const dtimestamp = today - index * 24 * 60 * 60 * 1000;
 | 
			
		||||
					return `${new Date(dtimestamp).getMonth() + 1}.${new Date(
 | 
			
		||||
						dtimestamp,
 | 
			
		||||
					).getDate()}`;
 | 
			
		||||
				})
 | 
			
		||||
				.reverse(),
 | 
			
		||||
			axisLabel: {
 | 
			
		||||
				color: '#fff',
 | 
			
		||||
				fontSize: 12,
 | 
			
		||||
			},
 | 
			
		||||
			axisTick: { show: false },
 | 
			
		||||
			axisLine: {
 | 
			
		||||
				lineStyle: {
 | 
			
		||||
					width: 1,
 | 
			
		||||
					color: '#213259',
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
		yAxis: {
 | 
			
		||||
			name: '单位m³/h',
 | 
			
		||||
			nameTextStyle: {
 | 
			
		||||
				color: '#fff',
 | 
			
		||||
				fontSize: 10,
 | 
			
		||||
				align: 'right',
 | 
			
		||||
			},
 | 
			
		||||
			type: 'value',
 | 
			
		||||
			axisLabel: {
 | 
			
		||||
				color: '#fff',
 | 
			
		||||
				fontSize: 12,
 | 
			
		||||
				formatter: '{value} %',
 | 
			
		||||
			},
 | 
			
		||||
			axisLine: {
 | 
			
		||||
				show: true,
 | 
			
		||||
				lineStyle: {
 | 
			
		||||
					color: '#213259',
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
			splitLine: {
 | 
			
		||||
				lineStyle: {
 | 
			
		||||
					color: '#213259a0',
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
			interval: 10,
 | 
			
		||||
			min: 0,
 | 
			
		||||
			max: 100,
 | 
			
		||||
		},
 | 
			
		||||
		series: [
 | 
			
		||||
			{
 | 
			
		||||
				data: Array(7)
 | 
			
		||||
					.fill(1)
 | 
			
		||||
					.map((_) => {
 | 
			
		||||
						return randomInt(60, 100);
 | 
			
		||||
					}),
 | 
			
		||||
				type: 'line',
 | 
			
		||||
				areaStyle: {
 | 
			
		||||
					color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
 | 
			
		||||
						{ offset: 0, color: '#FFD16040' },
 | 
			
		||||
						{ offset: 0.5, color: '#FFD16020' },
 | 
			
		||||
						{ offset: 1, color: '#FFD16010' },
 | 
			
		||||
					]),
 | 
			
		||||
				},
 | 
			
		||||
				// smooth: true,
 | 
			
		||||
			},
 | 
			
		||||
			{
 | 
			
		||||
				data: Array(7)
 | 
			
		||||
					.fill(1)
 | 
			
		||||
					.map((_) => {
 | 
			
		||||
						return randomInt(60, 100);
 | 
			
		||||
					}),
 | 
			
		||||
				type: 'line',
 | 
			
		||||
				areaStyle: {
 | 
			
		||||
					color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
 | 
			
		||||
						{ offset: 0, color: '#12FFF540' },
 | 
			
		||||
						{ offset: 0.5, color: '#12FFF520' },
 | 
			
		||||
						{ offset: 1, color: '#12FFF510' },
 | 
			
		||||
					]),
 | 
			
		||||
				},
 | 
			
		||||
				// smooth: true,
 | 
			
		||||
			},
 | 
			
		||||
			{
 | 
			
		||||
				data: Array(7)
 | 
			
		||||
					.fill(1)
 | 
			
		||||
					.map((_) => {
 | 
			
		||||
						return randomInt(60, 100);
 | 
			
		||||
					}),
 | 
			
		||||
				type: 'line',
 | 
			
		||||
				areaStyle: {
 | 
			
		||||
					color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
 | 
			
		||||
						{ offset: 0, color: '#2760FF40' },
 | 
			
		||||
						{ offset: 0.5, color: '#2760FF20' },
 | 
			
		||||
						{ offset: 1, color: '#2760FF10' },
 | 
			
		||||
					]),
 | 
			
		||||
				},
 | 
			
		||||
				// smooth: true,
 | 
			
		||||
			},
 | 
			
		||||
		],
 | 
			
		||||
		tooltip: {
 | 
			
		||||
			trigger: 'axis',
 | 
			
		||||
		},
 | 
			
		||||
	};
 | 
			
		||||
  const dayTrend = useSelector((state) => state.smoke?.dayTrend);
 | 
			
		||||
  const weekTrend = useSelector((state) => state.smoke?.weekTrend);
 | 
			
		||||
  const monthTrend = useSelector((state) => state.smoke?.monthTrend);
 | 
			
		||||
  const yearTrend = useSelector((state) => state.smoke?.yearTrend);
 | 
			
		||||
 | 
			
		||||
	function handleSwitchChange(val) {
 | 
			
		||||
		// val: boolean
 | 
			
		||||
		console.log('switch change', val);
 | 
			
		||||
	}
 | 
			
		||||
  const [source, setSource] = useState("O2_float");
 | 
			
		||||
  const [period, setPeriod] = useState("day");
 | 
			
		||||
 | 
			
		||||
	return (
 | 
			
		||||
		<div className={cls.energyCostChart}>
 | 
			
		||||
			<div className={cls.titleBar}>
 | 
			
		||||
				<h2>烟气趋势图</h2>
 | 
			
		||||
				<Switch defaultChecked onChange={handleSwitchChange} />
 | 
			
		||||
				<div className={cls.legend}>
 | 
			
		||||
					<span className="legend__title">班次详情</span>
 | 
			
		||||
					<ul className="legend__list">
 | 
			
		||||
						<li>总量</li>
 | 
			
		||||
						<li>白班</li>
 | 
			
		||||
						<li>夜班</li>
 | 
			
		||||
					</ul>
 | 
			
		||||
				</div>
 | 
			
		||||
			</div>
 | 
			
		||||
  const currentTrend =
 | 
			
		||||
    period === "day"
 | 
			
		||||
      ? dayTrend
 | 
			
		||||
      : period === "week"
 | 
			
		||||
      ? weekTrend
 | 
			
		||||
      : period === "month"
 | 
			
		||||
      ? monthTrend
 | 
			
		||||
      : yearTrend;
 | 
			
		||||
 | 
			
		||||
			<div className={`${cls.choiceBar} flex items-center justify-between`}>
 | 
			
		||||
				<Radio.Group
 | 
			
		||||
					defaultValue="oxygen"
 | 
			
		||||
					buttonStyle="solid"
 | 
			
		||||
					className={`${cls.radioGroup} flex items-center justify-between`}
 | 
			
		||||
				>
 | 
			
		||||
					<Radio.Button value="oxygen" className="radio-group__item">
 | 
			
		||||
						氧气含量
 | 
			
		||||
					</Radio.Button>
 | 
			
		||||
					<Radio.Button value="so2" className="radio-group__item">
 | 
			
		||||
						二氧化硫
 | 
			
		||||
					</Radio.Button>
 | 
			
		||||
					<Radio.Button value="no" className="radio-group__item">
 | 
			
		||||
						一氧化氮
 | 
			
		||||
					</Radio.Button>
 | 
			
		||||
					<Radio.Button value="no2" className="radio-group__item">
 | 
			
		||||
						二氧化氮
 | 
			
		||||
					</Radio.Button>
 | 
			
		||||
				</Radio.Group>
 | 
			
		||||
  const options = getOptions(source, period, currentTrend);
 | 
			
		||||
 | 
			
		||||
				<Radio.Group
 | 
			
		||||
					defaultValue="week"
 | 
			
		||||
					buttonStyle="solid"
 | 
			
		||||
					className={cls.radioGroup}
 | 
			
		||||
				>
 | 
			
		||||
					<Radio.Button value="day" className="radio-group__item">
 | 
			
		||||
						日
 | 
			
		||||
					</Radio.Button>
 | 
			
		||||
					<Radio.Button value="week" className="radio-group__item">
 | 
			
		||||
						周
 | 
			
		||||
					</Radio.Button>
 | 
			
		||||
					<Radio.Button value="month" className="radio-group__item">
 | 
			
		||||
						月
 | 
			
		||||
					</Radio.Button>
 | 
			
		||||
					<Radio.Button value="year" className="radio-group__item">
 | 
			
		||||
						年
 | 
			
		||||
					</Radio.Button>
 | 
			
		||||
				</Radio.Group>
 | 
			
		||||
			</div>
 | 
			
		||||
			<ReactECharts option={options} style={{ height: '240px' }} />
 | 
			
		||||
		</div>
 | 
			
		||||
	);
 | 
			
		||||
  const [desc, setDesc] = useState("");
 | 
			
		||||
 | 
			
		||||
  useEffect(() => {
 | 
			
		||||
    switch (period) {
 | 
			
		||||
      case "day":
 | 
			
		||||
        setDesc(
 | 
			
		||||
          dayjs().format("YYYY.MM.DD") +
 | 
			
		||||
            " 7点 - " +
 | 
			
		||||
            dayjs().add(1, "day").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>
 | 
			
		||||
  );
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
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,91 +1,102 @@
 | 
			
		||||
.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;
 | 
			
		||||
  border: none !important;
 | 
			
		||||
  border-radius: 0 !important;
 | 
			
		||||
}
 | 
			
		||||
.radioGroupShort * {
 | 
			
		||||
  border: none !important;
 | 
			
		||||
  border-radius: 6px !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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.graphBaseDesc {
 | 
			
		||||
  margin: 0 12px;
 | 
			
		||||
  line-height: 1;
 | 
			
		||||
  color: #76fff9;
 | 
			
		||||
  flex: 1;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,23 +1,19 @@
 | 
			
		||||
import cls from './index.module.scss';
 | 
			
		||||
import Container from '../../Container';
 | 
			
		||||
import TechSplitline from '../TechSplitline';
 | 
			
		||||
import SmokeTrendChart from './SmokeTrendChart';
 | 
			
		||||
import cls from "./index.module.scss";
 | 
			
		||||
import Container from "../../Container";
 | 
			
		||||
import TechSplitline from "../TechSplitline";
 | 
			
		||||
import SmokeTrendChart from "./SmokeTrendChart";
 | 
			
		||||
import SmokeHandleTable from "./SmokeHandleTable";
 | 
			
		||||
 | 
			
		||||
function SmokeHandle(props) {
 | 
			
		||||
	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>
 | 
			
		||||
	);
 | 
			
		||||
  return (
 | 
			
		||||
    <Container title="烟气处理" icon="smoke" className={cls.smokeHandle}>
 | 
			
		||||
      <div className={`${cls.smokeHandle__content} flex flex-col`}>
 | 
			
		||||
        <SmokeHandleTable />
 | 
			
		||||
        <TechSplitline />
 | 
			
		||||
        <SmokeTrendChart />
 | 
			
		||||
      </div>
 | 
			
		||||
    </Container>
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default SmokeHandle;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,31 +1,36 @@
 | 
			
		||||
.smokeHandle {
 | 
			
		||||
	// background: #b730305c;
 | 
			
		||||
	background: url(../../../assets/smoke.png) no-repeat;
 | 
			
		||||
	background-size: 100% 100%;
 | 
			
		||||
	width: 626px;
 | 
			
		||||
	height: 540px;
 | 
			
		||||
	.smokeHandle__content {
 | 
			
		||||
		margin-top: 8px;
 | 
			
		||||
	}
 | 
			
		||||
  // background: #b730305c;
 | 
			
		||||
  background: url(../../../assets/smoke.png) no-repeat;
 | 
			
		||||
  background-size: 100% 100%;
 | 
			
		||||
  width: 626px;
 | 
			
		||||
  height: 490px;
 | 
			
		||||
  .smokeHandle__content {
 | 
			
		||||
    margin-top: 8px;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.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);
 | 
			
		||||
	// width: 288px;
 | 
			
		||||
	height: 56px;
 | 
			
		||||
	font-size: 20px;
 | 
			
		||||
	letter-spacing: 1.43px;
 | 
			
		||||
	line-height: 56px;
 | 
			
		||||
	text-align: center;
 | 
			
		||||
	user-select: none;
 | 
			
		||||
  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;
 | 
			
		||||
  letter-spacing: 1.43px;
 | 
			
		||||
  line-height: 32px;
 | 
			
		||||
  text-align: center;
 | 
			
		||||
  user-select: none;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.info__item_groups {
 | 
			
		||||
	margin-bottom: 12px;
 | 
			
		||||
	margin-left: 8px;
 | 
			
		||||
	display: grid;
 | 
			
		||||
	grid-template-columns: 1fr 1fr;
 | 
			
		||||
	gap: 8px;
 | 
			
		||||
  margin-bottom: 12px;
 | 
			
		||||
  display: grid;
 | 
			
		||||
  grid-template-columns: 1fr 1fr;
 | 
			
		||||
  gap: 4px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.disabled {
 | 
			
		||||
  display: none;
 | 
			
		||||
  pointer-events: none;
 | 
			
		||||
  opacity: 0.5;
 | 
			
		||||
  color: transparent;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										55
									
								
								src/components/Common/TemperatureBottom/index.jsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,55 @@
 | 
			
		||||
import BlueRect from "../BlueRect";
 | 
			
		||||
import { useSelector } from "react-redux";
 | 
			
		||||
import { motion, AnimatePresence } from "framer-motion";
 | 
			
		||||
import { useEffect, useState } from "react";
 | 
			
		||||
 | 
			
		||||
const blueTe = ["TE401", "TE402", "TE403", "PE401", "PE402", "PE403"];
 | 
			
		||||
 | 
			
		||||
function TemperatureBottom(props) {
 | 
			
		||||
  const tempBottom = useSelector((state) => state.temperature.bottom);
 | 
			
		||||
  const speed = props.speed;
 | 
			
		||||
  const floor = props.floor;
 | 
			
		||||
  const [speedAn, setSpeedAn] = useState({});
 | 
			
		||||
  useEffect(() => {
 | 
			
		||||
    // 2,3互切不用展示动画
 | 
			
		||||
    if (speed === "f") {
 | 
			
		||||
      setSpeedAn({});
 | 
			
		||||
    } else {
 | 
			
		||||
      if (floor === 2) {
 | 
			
		||||
        setSpeedAn({
 | 
			
		||||
          opacity: [0, 0, 0, 0.6, 1],
 | 
			
		||||
          transition: { duration: 0.3, delay: 1.8 },
 | 
			
		||||
        });
 | 
			
		||||
      } else {
 | 
			
		||||
        setSpeedAn({});
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }, [floor]);
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    <motion.div
 | 
			
		||||
      className="temperature-bottom"
 | 
			
		||||
      style={{
 | 
			
		||||
        position: "absolute",
 | 
			
		||||
        top: "0",
 | 
			
		||||
        left: "0",
 | 
			
		||||
        width: "100%",
 | 
			
		||||
        height: "80vh",
 | 
			
		||||
        zIndex: "-1",
 | 
			
		||||
        ...props.style,
 | 
			
		||||
      }}
 | 
			
		||||
      animate={speedAn}
 | 
			
		||||
    >
 | 
			
		||||
      {Object.keys(tempBottom).map((d) => (
 | 
			
		||||
        <BlueRect
 | 
			
		||||
          title={d}
 | 
			
		||||
          key={d + Math.random()}
 | 
			
		||||
          value={tempBottom[d]}
 | 
			
		||||
          blue={blueTe.includes(d)}
 | 
			
		||||
        />
 | 
			
		||||
      ))}
 | 
			
		||||
    </motion.div>
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default TemperatureBottom;
 | 
			
		||||
							
								
								
									
										50
									
								
								src/components/Common/TemperatureTop/index.jsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,50 @@
 | 
			
		||||
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: 1.5 },
 | 
			
		||||
      }}
 | 
			
		||||
    >
 | 
			
		||||
      {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,11 +10,15 @@ 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 [min, sec] = useTimeCounter(time);
 | 
			
		||||
 | 
			
		||||
  const minsec = useTimeCounter(time);
 | 
			
		||||
  let [min, sec] = [0, 0];
 | 
			
		||||
  if (minsec) {
 | 
			
		||||
    min = minsec[0];
 | 
			
		||||
    sec = minsec[1];
 | 
			
		||||
  }
 | 
			
		||||
  // useEffect(() => {
 | 
			
		||||
  //   const restTime = ctx?.runState?.lastFireChangeTime;
 | 
			
		||||
  //   if (restTime == null) return;
 | 
			
		||||
@@ -76,22 +80,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
									
								
								src/components/Common/TodayFaultTotal/1.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1 @@
 | 
			
		||||
1.json
 | 
			
		||||
@@ -1,163 +1,211 @@
 | 
			
		||||
import cls from './index.module.css';
 | 
			
		||||
import GraphBase from '../GraphBase';
 | 
			
		||||
import ReactECharts from 'echarts-for-react';
 | 
			
		||||
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'
 | 
			
		||||
 | 
			
		||||
function FaultTotal(props) {
 | 
			
		||||
	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 [currentSelect, setCurrentSelect] = useState("日");
 | 
			
		||||
  const isra = useSelector((state) => state.isra);
 | 
			
		||||
 | 
			
		||||
	function handleDateChange(v) {
 | 
			
		||||
		console.log('date ', v);
 | 
			
		||||
	}
 | 
			
		||||
  const currentStatistic =
 | 
			
		||||
    currentSelect == "日"
 | 
			
		||||
      ? isra.dayStatistic
 | 
			
		||||
      : currentSelect == "周"
 | 
			
		||||
      ? isra.weekStatistic
 | 
			
		||||
      : currentSelect == "月"
 | 
			
		||||
      ? isra.monthStatistic
 | 
			
		||||
      : currentSelect == "月"
 | 
			
		||||
      ? isra.yearStatistic
 | 
			
		||||
      : [];
 | 
			
		||||
 | 
			
		||||
	// 根据使用的页面决定背景的大小
 | 
			
		||||
	const bgSize =
 | 
			
		||||
		props.page == 'home' ? ['middle', 'short'] : ['middle', 'long'];
 | 
			
		||||
  const series = preHandleStatisticData(currentStatistic, isra.checkType ?? []);
 | 
			
		||||
  const options = getOptions(series, isra, currentStatistic);
 | 
			
		||||
 | 
			
		||||
	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>
 | 
			
		||||
	);
 | 
			
		||||
  function handleDateChange(v) {
 | 
			
		||||
    setCurrentSelect(v);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // 根据使用的页面决定背景的大小
 | 
			
		||||
  const bgSize =
 | 
			
		||||
    props.page == "home" ? ["middle", "short"] : ["middle", "long"];
 | 
			
		||||
 | 
			
		||||
  // time hint
 | 
			
		||||
  let timeDesc = "";
 | 
			
		||||
  switch (currentSelect) {
 | 
			
		||||
    case "日":
 | 
			
		||||
      timeDesc = dayjs().format('YYYY.MM.DD') + " 7点 - " + dayjs().add(1, 'day').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="产线缺陷统计"
 | 
			
		||||
      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>
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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,107 +1,253 @@
 | 
			
		||||
import cls from './index.module.css';
 | 
			
		||||
import GraphBase from '../GraphBase';
 | 
			
		||||
import ReactECharts from 'echarts-for-react';
 | 
			
		||||
import { useState } from 'react';
 | 
			
		||||
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 * as echarts from "echarts";
 | 
			
		||||
import dayjs from "dayjs";
 | 
			
		||||
 | 
			
		||||
function FaultType(props) {
 | 
			
		||||
	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' },
 | 
			
		||||
				],
 | 
			
		||||
			},
 | 
			
		||||
		],
 | 
			
		||||
	};
 | 
			
		||||
  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 timestr =
 | 
			
		||||
    dayjs().format("YYYY.MM.DD") +
 | 
			
		||||
    " 7点 - " +
 | 
			
		||||
    dayjs().add(1, "d").format("YYYY.MM.DD") +
 | 
			
		||||
    " 7点";
 | 
			
		||||
 | 
			
		||||
	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' },
 | 
			
		||||
	]);
 | 
			
		||||
  useEffect(() => {
 | 
			
		||||
    if (init == false) return;
 | 
			
		||||
    if (lines.length) {
 | 
			
		||||
      setInit(false);
 | 
			
		||||
      setCurrentLine(lines[0]);
 | 
			
		||||
    }
 | 
			
		||||
  }, [lines]);
 | 
			
		||||
 | 
			
		||||
	function handleDateChange(v) {
 | 
			
		||||
		console.log('date ', v);
 | 
			
		||||
	}
 | 
			
		||||
  const options = init
 | 
			
		||||
    ? {}
 | 
			
		||||
    : getOptions(
 | 
			
		||||
        CHART_TYPE == "pie"
 | 
			
		||||
          ? getSeries(currentStatistic, currentLine)
 | 
			
		||||
          : currentLineStatistic,
 | 
			
		||||
        CHART_TYPE
 | 
			
		||||
      );
 | 
			
		||||
 | 
			
		||||
	// 根据使用的页面决定背景的大小
 | 
			
		||||
	const bgSize =
 | 
			
		||||
		props.page == 'home' ? ['middle', 'short'] : ['middle', 'short'];
 | 
			
		||||
  function handleLineChange(line) {
 | 
			
		||||
    setCurrentLine(line);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
	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>
 | 
			
		||||
	);
 | 
			
		||||
  // 根据使用的页面决定背景的大小
 | 
			
		||||
  const bgSize =
 | 
			
		||||
    props.page == "home" ? ["middle", "short"] : ["middle", "short"];
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    <GraphBase
 | 
			
		||||
      icon="default"
 | 
			
		||||
      title="产线当日缺陷分类"
 | 
			
		||||
      desc={timestr}
 | 
			
		||||
      descSmall={true}
 | 
			
		||||
      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>
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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,155 +1,313 @@
 | 
			
		||||
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';
 | 
			
		||||
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: "年" };
 | 
			
		||||
 | 
			
		||||
const GoodRateChart = (props) => {
 | 
			
		||||
	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',
 | 
			
		||||
		},
 | 
			
		||||
	};
 | 
			
		||||
  // 是否展示班次数据
 | 
			
		||||
  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]);
 | 
			
		||||
 | 
			
		||||
	function handleSwitchChange(val) {
 | 
			
		||||
		// val: boolean
 | 
			
		||||
		console.log('switch change', val);
 | 
			
		||||
	}
 | 
			
		||||
  function handleSwitchChange(val) {
 | 
			
		||||
    // val: boolean
 | 
			
		||||
    setShowMore(val);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
	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>
 | 
			
		||||
	);
 | 
			
		||||
  const [timestr, setTimestr] = useState(
 | 
			
		||||
    dayjs().format("YYYY.MM.DD") +
 | 
			
		||||
      " 7点 - " +
 | 
			
		||||
      dayjs().add(1, "day").format("YYYY.MM.DD") +
 | 
			
		||||
      " 7点"
 | 
			
		||||
  );
 | 
			
		||||
  function handleDateChange(value) {
 | 
			
		||||
    // e: Event
 | 
			
		||||
    let v = "day";
 | 
			
		||||
    switch (value) {
 | 
			
		||||
      case "日":
 | 
			
		||||
        setTimestr(
 | 
			
		||||
          dayjs().format("YYYY.MM.DD") +
 | 
			
		||||
            " 7点 - " +
 | 
			
		||||
            dayjs().add(1, "day").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>
 | 
			
		||||
  );
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
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,86 +1,95 @@
 | 
			
		||||
.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: space-between;
 | 
			
		||||
	align-items: center;
 | 
			
		||||
	color: white;
 | 
			
		||||
  display: flex;
 | 
			
		||||
  justify-content: flex-start;
 | 
			
		||||
  align-items: center;
 | 
			
		||||
  gap: 5px;
 | 
			
		||||
  color: white;
 | 
			
		||||
}
 | 
			
		||||
.GoodRateChart .titleBar h2 {
 | 
			
		||||
	margin: 0;
 | 
			
		||||
	font-size: 18px;
 | 
			
		||||
	line-height: 32px;
 | 
			
		||||
	letter-spacing: 1.2px;
 | 
			
		||||
	color: #52fff8;
 | 
			
		||||
  margin: 0;
 | 
			
		||||
  font-size: 16px;
 | 
			
		||||
  line-height: 32px;
 | 
			
		||||
  letter-spacing: 1px;
 | 
			
		||||
  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;
 | 
			
		||||
  font-size: 14px;
 | 
			
		||||
  line-height: 14px;
 | 
			
		||||
  color: #dff1fe;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.graphBaseDesc {
 | 
			
		||||
  margin: 0 6px;
 | 
			
		||||
  font-size: 16px;
 | 
			
		||||
  color: #76fff9;
 | 
			
		||||
  flex: 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.GoodRateChart .titleBar .legend ul {
 | 
			
		||||
	display: flex;
 | 
			
		||||
	margin: 0;
 | 
			
		||||
	margin-left: 8px;
 | 
			
		||||
	padding: 0;
 | 
			
		||||
	list-style: none;
 | 
			
		||||
	align-items: center;
 | 
			
		||||
  display: flex;
 | 
			
		||||
  margin: 0;
 | 
			
		||||
  margin-left: 5px;
 | 
			
		||||
  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: 0 !important;
 | 
			
		||||
  border: none !important;
 | 
			
		||||
  border-radius: 6px !important;
 | 
			
		||||
  /* transform: translateX(224px) !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,34 +1,82 @@
 | 
			
		||||
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 [config, setConfig] = useState({
 | 
			
		||||
  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 = {
 | 
			
		||||
    // headerBGC: 'rgba(4, 44, 76, 0.3)',
 | 
			
		||||
    headerBGC: "rgba(4, 44, 76, .8)",
 | 
			
		||||
    // headerBGC: "rgba(4, 44, 76, .8)",
 | 
			
		||||
    headerBGC: "#044A8460",
 | 
			
		||||
    header: [
 | 
			
		||||
      '<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/>',
 | 
			
		||||
      '<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/>',
 | 
			
		||||
    ],
 | 
			
		||||
    oddRowBGC: "#042444",
 | 
			
		||||
    evenRowBGC: "#042c4c",
 | 
			
		||||
    // oddRowBGC: "#042444",
 | 
			
		||||
    // evenRowBGC: "#042c4c",
 | 
			
		||||
    oddRowBGC: "#044A8460",
 | 
			
		||||
    evenRowBGC: "#0b549970",
 | 
			
		||||
    columnWidth: [90],
 | 
			
		||||
    headerHeight: 40,
 | 
			
		||||
    hoverPause: false,
 | 
			
		||||
    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%"],
 | 
			
		||||
    ],
 | 
			
		||||
  });
 | 
			
		||||
    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%"],
 | 
			
		||||
    // ],
 | 
			
		||||
  };
 | 
			
		||||
  return (
 | 
			
		||||
    <div className={cls.todayTableData}>
 | 
			
		||||
      <ScrollBoard config={config} style={{ width: "100%" }} />
 | 
			
		||||
      {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>
 | 
			
		||||
      )}
 | 
			
		||||
    </div>
 | 
			
		||||
  );
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										40
									
								
								src/components/Common/VideoMonitor/index.jsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,40 @@
 | 
			
		||||
// import cls from "./index.module.css";
 | 
			
		||||
import "./video-monitor.css";
 | 
			
		||||
 | 
			
		||||
function VideoMonitor(props) {
 | 
			
		||||
  return (
 | 
			
		||||
    <div className="video-monitor">
 | 
			
		||||
      <h2>泡界线监控</h2>
 | 
			
		||||
      <div className="video-container">
 | 
			
		||||
        <div>
 | 
			
		||||
          {/* <video muted autoPlay loop src="https://storage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4"></video> */}
 | 
			
		||||
          <img
 | 
			
		||||
            style={{
 | 
			
		||||
              width: "100%",
 | 
			
		||||
              height: "100%",
 | 
			
		||||
              display: "block",
 | 
			
		||||
              margin: "auto",
 | 
			
		||||
              backgrounColor: "hsl(0, 0%, 25%)",
 | 
			
		||||
            }}
 | 
			
		||||
            src="http://10.70.180.10:8001/video_feed"
 | 
			
		||||
          ></img>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div>
 | 
			
		||||
          {/* <video muted autoPlay loop src="https://storage.googleapis.com/gtv-videos-bucket/sample/ForBiggerEscapes.mp4"></video> */}
 | 
			
		||||
          <img
 | 
			
		||||
            style={{
 | 
			
		||||
              width: "100%",
 | 
			
		||||
              height: "100%",
 | 
			
		||||
              display: "block",
 | 
			
		||||
              margin: "auto",
 | 
			
		||||
              backgrounColor: "hsl(0, 0%, 25%)",
 | 
			
		||||
            }}
 | 
			
		||||
            src="http://10.70.180.10:8000/video_feed"
 | 
			
		||||
          ></img>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default VideoMonitor;
 | 
			
		||||
							
								
								
									
										35
									
								
								src/components/Common/VideoMonitor/video-monitor.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,35 @@
 | 
			
		||||
.video-monitor {
 | 
			
		||||
  display: flex;
 | 
			
		||||
  flex-direction: column;
 | 
			
		||||
  margin-left: 80px;
 | 
			
		||||
  height: 200px;
 | 
			
		||||
  width: 500px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.video-monitor > h2 {
 | 
			
		||||
  margin: 0;
 | 
			
		||||
  padding: 10px 0;
 | 
			
		||||
  background: #16253c;
 | 
			
		||||
  color: #fff;
 | 
			
		||||
  font-weight: 400;
 | 
			
		||||
  letter-spacing: 2px;
 | 
			
		||||
  font-size: 18px;
 | 
			
		||||
  text-align: center;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.video-monitor > .video-container {
 | 
			
		||||
  display: flex;
 | 
			
		||||
  gap: 8px;
 | 
			
		||||
  flex: 1;
 | 
			
		||||
  max-height: 150px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.video-container > div {
 | 
			
		||||
  flex: 1;
 | 
			
		||||
  height: 100%;
 | 
			
		||||
  background: #ccc1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.video-container > div > video {
 | 
			
		||||
  width: 100%;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								src/components/Common/WarnAlert/3.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 1.3 KiB  | 
							
								
								
									
										130
									
								
								src/components/Common/WarnAlert/ListContainer.jsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,130 @@
 | 
			
		||||
import WarnAlert from ".";
 | 
			
		||||
import { useSelector } from "react-redux";
 | 
			
		||||
import posMap from "./position.json";
 | 
			
		||||
 | 
			
		||||
const total = `AN_1_1,助燃风故障报警
 | 
			
		||||
AN_1_2,压延机冷却风故障报警
 | 
			
		||||
AN_1_3,L吊墙冷却风机故障报警
 | 
			
		||||
AN_1_4,熔化带及部分澄清部冷却风机故障报警
 | 
			
		||||
AN_2_1,澄清带池壁冷却风机故障报警
 | 
			
		||||
AN_2_2,钢碴碴冷却风机故障报警
 | 
			
		||||
AN_2_3,支通路拐角冷却风机报警
 | 
			
		||||
AN_2_4,吊墙吊钩砖结构温升报警
 | 
			
		||||
AN_3_1,深层水包冷却水温升报警
 | 
			
		||||
AN_3_2,深层水包冷却水断水报警
 | 
			
		||||
AN_3_3,卡脖吊平冷却水断水报警
 | 
			
		||||
AN_3_4,卡脖吊平喧冷却水温升报警
 | 
			
		||||
AN_4_1,液面计冷却水断水报警
 | 
			
		||||
AN_4_2,液面计冷却水温升报警
 | 
			
		||||
AN_4_3,循环水入口压力低报警
 | 
			
		||||
AN_4_4,天然气压力高低报警
 | 
			
		||||
AN_5_1,助燃风风压低报警
 | 
			
		||||
AN_5_2,净化压缩气压力低报警
 | 
			
		||||
AN_5_3,普通压缩空气压力高低报警
 | 
			
		||||
AN_5_4,焦炉煤气气压力高低报警
 | 
			
		||||
AN_6_1,换向过程故障报警
 | 
			
		||||
AN_6_2,空交机换向不到位报警
 | 
			
		||||
AN_6_3,投料机故障报警
 | 
			
		||||
AN_6_4,备用
 | 
			
		||||
AN_7_1,1#压延机冷却水断水报警
 | 
			
		||||
AN_7_2,1#压延机冷却水温升报警
 | 
			
		||||
AN_7_3,1#过渡辊台冷却水断水报警
 | 
			
		||||
AN_7_4,1过渡辊台冷却水温升报警
 | 
			
		||||
AN_8_1,1#线唇砖冷却水断水报警
 | 
			
		||||
AN_8_2,1#线唇砖冷却水温升报警
 | 
			
		||||
AN_8_3,1#退火窑A区风机报警
 | 
			
		||||
AN_8_4,1#退火窑B区风机报警
 | 
			
		||||
AN_9_1,1#退火窑c区风机报警
 | 
			
		||||
AN_9_2,1#退火窑Ret1区风机报警
 | 
			
		||||
AN_9_3,1#退火窑Ret2区风机报警
 | 
			
		||||
AN_9_4,1#退火窑F1区风机报警
 | 
			
		||||
AN_10_1,1#退火窑F2区风机报警
 | 
			
		||||
AN_10_2,1#主传动报警
 | 
			
		||||
AN_10_3,1#压延机报警
 | 
			
		||||
AN_10_4,备用
 | 
			
		||||
AN_11_1,2#压延机冷却水断水报警
 | 
			
		||||
AN_11_2,2#压延机冷却水温升报警
 | 
			
		||||
AN_11_3,2#过渡辊台冷却水断水报警
 | 
			
		||||
AN_11_4,2#过渡辊台冷却水温升报警
 | 
			
		||||
AN_12_1,2#线唇砖冷却水断水报警
 | 
			
		||||
AN_12_2,2#线唇砖冷却水温升报警
 | 
			
		||||
AN_12_3,2#退火窑A区风机报警
 | 
			
		||||
AN_12_4,2#退火窑B区风机报警
 | 
			
		||||
AN_13_1,2#退火窑c区风机报警
 | 
			
		||||
AN_13_2,2#退火窑Ret1区风机报警
 | 
			
		||||
AN_13_3,2#退火窑Ret2区风机报警
 | 
			
		||||
AN_13_4,2#退火窑F1区风机报警
 | 
			
		||||
AN_14_1,2#退火窑F2区风机报警
 | 
			
		||||
AN_14_2,2#主传动报警
 | 
			
		||||
AN_14_3,2#压延机报警
 | 
			
		||||
AN_14_4,备用
 | 
			
		||||
AN_15_1,3#压延机冷却水断水报警
 | 
			
		||||
AN_15_2,3压延机冷却水温升报警
 | 
			
		||||
AN_15_3,3#过渡辊台冷却水断水报警
 | 
			
		||||
AN_15_4,3#过渡辊台冷却水温升报警
 | 
			
		||||
AN_16_1,3#线唇砖冷却水断水报警
 | 
			
		||||
AN_16_2,3#线唇砖冷却水温升报警
 | 
			
		||||
AN_16_3,3#退火窑A区风机报警
 | 
			
		||||
AN_16_4,3#退火窑B区风机报警
 | 
			
		||||
AN_17_1,3#退火窑c区风机报警
 | 
			
		||||
AN_17_2,3#退火窑Ret1区风机报警
 | 
			
		||||
AN_17_3,3#退火窑Ret2区风机报警
 | 
			
		||||
AN_17_4,3#退火窑F1区风机报警
 | 
			
		||||
AN_18_1,3#退火窑F2区风机报警
 | 
			
		||||
AN_18_2,3#主传动报警
 | 
			
		||||
AN_18_3,3#压延机报警
 | 
			
		||||
AN_18_4,备用
 | 
			
		||||
AN_19_1,4#压延机冷却水断水报警
 | 
			
		||||
AN_19_2,4压延机冷却水温升报警
 | 
			
		||||
AN_19_3,4#过渡辊台冷却水断水报警
 | 
			
		||||
AN_19_4,4#过渡辊台冷却水温升报警
 | 
			
		||||
AN_20_1,4#线唇砖冷却水断水报警
 | 
			
		||||
AN_20_2,4#线唇砖冷却水温升报警
 | 
			
		||||
AN_20_3,4#退火窑A区风机报警
 | 
			
		||||
AN_20_4,4#退火窑B区风机报警
 | 
			
		||||
AN_21_1,4#退火窑c区风机报警
 | 
			
		||||
AN_21_2,4#退火窑Ret1区风机报警
 | 
			
		||||
AN_21_3,4#退火窑Ret2区风机报警
 | 
			
		||||
AN_21_4,4#退火窑F1区风机报警
 | 
			
		||||
AN_22_1,4#退火窑F2区风机报警
 | 
			
		||||
AN_22_2,4#主传动报警
 | 
			
		||||
AN_22_3,4#压延机报警
 | 
			
		||||
AN_23_1,5#压延机冷却水断水报警
 | 
			
		||||
AN_23_2,5#压延机冷却水温升报警
 | 
			
		||||
AN_23_3,5#过渡辊台冷却水断水报警
 | 
			
		||||
AN_23_4,5#过渡台冷却水温升报警
 | 
			
		||||
AN_24_1,5#线唇砖冷却水断水报警
 | 
			
		||||
AN_24_2,5#线唇砖冷却水温升报警
 | 
			
		||||
AN_24_3,5#退火窑A区风机报警
 | 
			
		||||
AN_24_4,5#退火窑B区风机报警
 | 
			
		||||
AN_25_1,5#退火窑c区风机报警
 | 
			
		||||
AN_25_2,5#退火窑Ret1区风机报警
 | 
			
		||||
AN_25_3,5#退火窑Ret2区风机报警
 | 
			
		||||
AN_25_4,5#退火窑F1区风机报警
 | 
			
		||||
AN_26_1,5#退火窑F2区风机报警
 | 
			
		||||
AN_26_2,5#主传动报警
 | 
			
		||||
AN_26_3,5#压延机报警
 | 
			
		||||
`;
 | 
			
		||||
 | 
			
		||||
function AlarmListContainer(props) {
 | 
			
		||||
  const alarmList = useSelector((state) => state.alarm.list);
 | 
			
		||||
  // const alarmList = total
 | 
			
		||||
  //   .split("\n")
 | 
			
		||||
  //   .filter((str) => str.trim())
 | 
			
		||||
  //   .map((item) => ({
 | 
			
		||||
  //     id: item.split(",")[0],
 | 
			
		||||
  //     title: item.split(",")[0],
 | 
			
		||||
  //     content: item.split(",")[1],
 | 
			
		||||
  //   }));
 | 
			
		||||
  return alarmList.map((alarm) => (
 | 
			
		||||
    <WarnAlert
 | 
			
		||||
      key={alarm.id}
 | 
			
		||||
      title={alarm.title}
 | 
			
		||||
      content={alarm.content}
 | 
			
		||||
      x={posMap[alarm.title]?.x || 0}
 | 
			
		||||
      y={posMap[alarm.title]?.y || 0}
 | 
			
		||||
    />
 | 
			
		||||
  ));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default AlarmListContainer;
 | 
			
		||||
							
								
								
									
										18
									
								
								src/components/Common/WarnAlert/index.jsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,18 @@
 | 
			
		||||
// import cls from "./index.module.css";
 | 
			
		||||
import "./warn-alert.css";
 | 
			
		||||
import AlertIcon from "./warn-icon.png";
 | 
			
		||||
 | 
			
		||||
function WarnAlert(props) {
 | 
			
		||||
  const { x, y, title, content } = props;
 | 
			
		||||
  return (
 | 
			
		||||
    <div className="warn-alert" style={{ top: `${y}px`, left: `${x}px` }}>
 | 
			
		||||
      <h1 className="">
 | 
			
		||||
        <img src={AlertIcon} width={24} alt="icon" />
 | 
			
		||||
        {title || "test"}
 | 
			
		||||
      </h1>
 | 
			
		||||
      <p>{content || "Lorem ipsum dolor sit amet consectetur."}</p>
 | 
			
		||||
    </div>
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default WarnAlert;
 | 
			
		||||
							
								
								
									
										104
									
								
								src/components/Common/WarnAlert/position.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,104 @@
 | 
			
		||||
{
 | 
			
		||||
  "AN_1_1": { "x": 650, "y": 645 },
 | 
			
		||||
  "AN_1_2": { "x": 1450, "y": 540 },
 | 
			
		||||
  "AN_1_3": { "x": 640, "y": 285 },
 | 
			
		||||
  "AN_1_4": { "x": 720, "y": 645 },
 | 
			
		||||
  "AN_2_1": { "x": 1250, "y": 540 },
 | 
			
		||||
  "AN_2_2": { "x": 1200, "y": 540 },
 | 
			
		||||
  "AN_2_3": { "x": 1460, "y": 410 },
 | 
			
		||||
  "AN_2_4": { "x": 650, "y": 420 },
 | 
			
		||||
  "AN_3_1": { "x": 1360, "y": 380 },
 | 
			
		||||
  "AN_3_2": { "x": 1360, "y": 380 },
 | 
			
		||||
  "AN_3_3": { "x": 1360, "y": 420 },
 | 
			
		||||
  "AN_3_4": { "x": 1360, "y": 420 },
 | 
			
		||||
  "AN_4_1": { "x": 1350, "y": 460 },
 | 
			
		||||
  "AN_4_2": { "x": 1350, "y": 460 },
 | 
			
		||||
  "AN_4_3": { "x": 1270, "y": 320 },
 | 
			
		||||
  "AN_4_4": { "x": 900, "y": 420 },
 | 
			
		||||
  "AN_5_1": { "x": 650, "y": 645 },
 | 
			
		||||
  "AN_5_2": { "x": 980, "y": 420 },
 | 
			
		||||
  "AN_5_3": { "x": 1050, "y": 420 },
 | 
			
		||||
  "AN_5_4": { "x": 1130, "y": 420 },
 | 
			
		||||
  "AN_6_1": { "x": 1220, "y": 420 },
 | 
			
		||||
  "AN_6_2": { "x": 1290, "y": 420 },
 | 
			
		||||
  "AN_6_3": { "x": 650, "y": 440 },
 | 
			
		||||
  "AN_6_4": { "x": 1400, "y": 650 },
 | 
			
		||||
  "AN_7_1": { "x": 1450, "y": 540 },
 | 
			
		||||
  "AN_7_2": { "x": 1450, "y": 540 },
 | 
			
		||||
  "AN_7_3": { "x": 1470, "y": 540 },
 | 
			
		||||
  "AN_7_4": { "x": 1470, "y": 540 },
 | 
			
		||||
  "AN_8_1": { "x": 1470, "y": 540 },
 | 
			
		||||
  "AN_8_2": { "x": 1470, "y": 540 },
 | 
			
		||||
  "AN_8_3": { "x": 1480, "y": 540 },
 | 
			
		||||
  "AN_8_4": { "x": 1580, "y": 540 },
 | 
			
		||||
  "AN_9_1": { "x": 1700, "y": 540 },
 | 
			
		||||
  "AN_9_2": { "x": 1760, "y": 540 },
 | 
			
		||||
  "AN_9_3": { "x": 1780, "y": 540 },
 | 
			
		||||
  "AN_9_4": { "x": 1780, "y": 540 },
 | 
			
		||||
  "AN_10_1": { "x": 1780, "y": 540 },
 | 
			
		||||
  "AN_10_2": { "x": 1390, "y": 540 },
 | 
			
		||||
  "AN_10_3": { "x": 1450, "y": 540 },
 | 
			
		||||
  "AN_10_4": { "x": 1400, "y": 650 },
 | 
			
		||||
  "AN_11_1": { "x": 1450, "y": 480 },
 | 
			
		||||
  "AN_11_2": { "x": 1450, "y": 480 },
 | 
			
		||||
  "AN_11_3": { "x": 1450, "y": 480 },
 | 
			
		||||
  "AN_11_4": { "x": 1450, "y": 480 },
 | 
			
		||||
  "AN_12_1": { "x": 1450, "y": 480 },
 | 
			
		||||
  "AN_12_2": { "x": 1450, "y": 480 },
 | 
			
		||||
  "AN_12_3": { "x": 1550, "y": 480 },
 | 
			
		||||
  "AN_12_4": { "x": 1650, "y": 480 },
 | 
			
		||||
  "AN_13_1": { "x": 1750, "y": 480 },
 | 
			
		||||
  "AN_13_2": { "x": 1850, "y": 480 },
 | 
			
		||||
  "AN_13_3": { "x": 1900, "y": 480 },
 | 
			
		||||
  "AN_13_4": { "x": 1910, "y": 480 },
 | 
			
		||||
  "AN_14_1": { "x": 1920, "y": 480 },
 | 
			
		||||
  "AN_14_2": { "x": 1450, "y": 480 },
 | 
			
		||||
  "AN_14_3": { "x": 1450, "y": 480 },
 | 
			
		||||
  "AN_14_4": { "x": 1400, "y": 650 },
 | 
			
		||||
  "AN_15_1": { "x": 1450, "y": 430 },
 | 
			
		||||
  "AN_15_2": { "x": 1450, "y": 430 },
 | 
			
		||||
  "AN_15_3": { "x": 1470, "y": 430 },
 | 
			
		||||
  "AN_15_4": { "x": 1470, "y": 430 },
 | 
			
		||||
  "AN_16_1": { "x": 1470, "y": 430 },
 | 
			
		||||
  "AN_16_2": { "x": 1470, "y": 430 },
 | 
			
		||||
  "AN_16_3": { "x": 1600, "y": 430 },
 | 
			
		||||
  "AN_16_4": { "x": 1700, "y": 430 },
 | 
			
		||||
  "AN_17_1": { "x": 1800, "y": 430 },
 | 
			
		||||
  "AN_17_2": { "x": 1900, "y": 430 },
 | 
			
		||||
  "AN_17_3": { "x": 1950, "y": 430 },
 | 
			
		||||
  "AN_17_4": { "x": 1960, "y": 430 },
 | 
			
		||||
  "AN_18_1": { "x": 1970, "y": 430 },
 | 
			
		||||
  "AN_18_2": { "x": 1450, "y": 430 },
 | 
			
		||||
  "AN_18_3": { "x": 1450, "y": 430 },
 | 
			
		||||
  "AN_18_4": { "x": 1400, "y": 650 },
 | 
			
		||||
  "AN_19_1": { "x": 1450, "y": 370 },
 | 
			
		||||
  "AN_19_2": { "x": 1450, "y": 370 },
 | 
			
		||||
  "AN_19_3": { "x": 1460, "y": 370 },
 | 
			
		||||
  "AN_19_4": { "x": 1460, "y": 370 },
 | 
			
		||||
  "AN_20_1": { "x": 1460, "y": 370 },
 | 
			
		||||
  "AN_20_2": { "x": 1460, "y": 370 },
 | 
			
		||||
  "AN_20_3": { "x": 1500, "y": 370 },
 | 
			
		||||
  "AN_20_4": { "x": 1600, "y": 370 },
 | 
			
		||||
  "AN_21_1": { "x": 1700, "y": 370 },
 | 
			
		||||
  "AN_21_2": { "x": 1800, "y": 370 },
 | 
			
		||||
  "AN_21_3": { "x": 1850, "y": 370 },
 | 
			
		||||
  "AN_21_4": { "x": 1860, "y": 370 },
 | 
			
		||||
  "AN_22_1": { "x": 1870, "y": 370 },
 | 
			
		||||
  "AN_22_2": { "x": 1450, "y": 370 },
 | 
			
		||||
  "AN_22_3": { "x": 1460, "y": 370 },
 | 
			
		||||
  "AN_23_1": { "x": 1460, "y": 320 },
 | 
			
		||||
  "AN_23_2": { "x": 1460, "y": 320 },
 | 
			
		||||
  "AN_23_3": { "x": 1465, "y": 320 },
 | 
			
		||||
  "AN_23_4": { "x": 1465, "y": 320 },
 | 
			
		||||
  "AN_24_1": { "x": 1465, "y": 320 },
 | 
			
		||||
  "AN_24_2": { "x": 1465, "y": 320 },
 | 
			
		||||
  "AN_24_3": { "x": 1480, "y": 320 },
 | 
			
		||||
  "AN_24_4": { "x": 1580, "y": 320 },
 | 
			
		||||
  "AN_25_1": { "x": 1680, "y": 320 },
 | 
			
		||||
  "AN_25_2": { "x": 1780, "y": 320 },
 | 
			
		||||
  "AN_25_3": { "x": 1750, "y": 320 },
 | 
			
		||||
  "AN_25_4": { "x": 1760, "y": 320 },
 | 
			
		||||
  "AN_26_1": { "x": 1770, "y": 320 },
 | 
			
		||||
  "AN_26_2": { "x": 1430, "y": 320 },
 | 
			
		||||
  "AN_26_3": { "x": 1460, "y": 320 }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										65
									
								
								src/components/Common/WarnAlert/warn-alert.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,65 @@
 | 
			
		||||
.warn-alert {
 | 
			
		||||
  position: fixed;
 | 
			
		||||
  top: 200px;
 | 
			
		||||
  left: 200px;
 | 
			
		||||
  /* height: 72px; */
 | 
			
		||||
  z-index: 10000;
 | 
			
		||||
  display: inline-block;
 | 
			
		||||
  /* background: url(../../../assets/warn-bg.png) 0 0 / 116px 100% repeat-x; */
 | 
			
		||||
  background: url(./3.png) 0 0 / 116px 100% repeat-x;
 | 
			
		||||
  box-shadow: 0 0 24px 6px rgba(0, 0, 0, 0.5);
 | 
			
		||||
  user-select: none;
 | 
			
		||||
  transform: scale(1);
 | 
			
		||||
  cursor: pointer;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.warn-alert:hover {
 | 
			
		||||
  transform: scale(1.1);
 | 
			
		||||
  box-shadow: 0 0 32px 12px rgba(0, 0, 0, 0.5);
 | 
			
		||||
  z-index: 10001;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.warn-alert::before {
 | 
			
		||||
  box-sizing: border-box;
 | 
			
		||||
  content: "";
 | 
			
		||||
  position: absolute;
 | 
			
		||||
  top: 0;
 | 
			
		||||
  left: -24px;
 | 
			
		||||
  width: 24px;
 | 
			
		||||
  height: 100%;
 | 
			
		||||
  display: inline-block;
 | 
			
		||||
  border: 12px solid transparent;
 | 
			
		||||
  border-right-color: #ff2c2c;
 | 
			
		||||
}
 | 
			
		||||
.warn-alert::after {
 | 
			
		||||
  box-sizing: border-box;
 | 
			
		||||
  content: "";
 | 
			
		||||
  position: absolute;
 | 
			
		||||
  top: 0;
 | 
			
		||||
  right: -24px;
 | 
			
		||||
  width: 24px;
 | 
			
		||||
  height: 100%;
 | 
			
		||||
  display: inline-block;
 | 
			
		||||
  border: 12px solid transparent;
 | 
			
		||||
  border-left-color: #ff2c2c;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.warn-alert > h1 {
 | 
			
		||||
  display: flex;
 | 
			
		||||
  margin: 8px 0 0;
 | 
			
		||||
  align-items: center;
 | 
			
		||||
  color: #fff;
 | 
			
		||||
  font-size: 16px;
 | 
			
		||||
  text-transform: uppercase;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.warn-alert > h1 img {
 | 
			
		||||
  padding-top: 3px;
 | 
			
		||||
  margin-left: 10px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.warn-alert > p {
 | 
			
		||||
  color: #fff;
 | 
			
		||||
  margin: 0 22px 16px 14px;
 | 
			
		||||
  font-size: 14px;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								src/components/Common/WarnAlert/warn-icon.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 2.2 KiB  | 
@@ -1,23 +1,44 @@
 | 
			
		||||
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);
 | 
			
		||||
 | 
			
		||||
	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>
 | 
			
		||||
	);
 | 
			
		||||
  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>
 | 
			
		||||
  );
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export default Container;
 | 
			
		||||
 
 | 
			
		||||