第一次提交
27
src/App.css
Normal file
@@ -0,0 +1,27 @@
|
||||
.background {
|
||||
height: 1080px;
|
||||
width: 5760px;
|
||||
background: url(/public/image/background.png) 100% no-repeat;
|
||||
background-size: 100% 100%;
|
||||
position: relative;
|
||||
}
|
||||
.flex-row {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
.flex-col {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.dejin-chart-tooltip {
|
||||
background: #0a2b4f77 !important;
|
||||
border: none !important;
|
||||
backdrop-filter: blur(12px);
|
||||
}
|
||||
|
||||
.dejin-chart-tooltip * {
|
||||
color: #fff !important;
|
||||
}
|
||||
p {
|
||||
margin: 0;
|
||||
}
|
||||
24
src/App.tsx
Normal file
@@ -0,0 +1,24 @@
|
||||
import "./App.css";
|
||||
import { createHashRouter, RouterProvider } from "react-router-dom";
|
||||
|
||||
import ErrorPage from "./page/ErrorPage";
|
||||
import HomePage from "./page/HomePage";
|
||||
|
||||
function App() {
|
||||
|
||||
const router = createHashRouter([
|
||||
{
|
||||
path: "/",
|
||||
element: <HomePage />,
|
||||
errorElement: <ErrorPage />,
|
||||
},
|
||||
]);
|
||||
|
||||
return (
|
||||
<div className="background">
|
||||
<RouterProvider router={router} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default App;
|
||||
BIN
src/assets/fonts/DINCondensed.ttf
Normal file
BIN
src/assets/fonts/站酷庆科黄油体.ttf
Normal file
BIN
src/assets/image/change_fire.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
src/assets/image/eq_icon1.png
Normal file
|
After Width: | Height: | Size: 3.7 KiB |
BIN
src/assets/image/eq_icon2.png
Normal file
|
After Width: | Height: | Size: 3.7 KiB |
BIN
src/assets/image/eq_icon3.png
Normal file
|
After Width: | Height: | Size: 3.9 KiB |
BIN
src/assets/image/eq_icon4.png
Normal file
|
After Width: | Height: | Size: 4.8 KiB |
BIN
src/assets/image/fire.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
src/assets/image/press_img.png
Normal file
|
After Width: | Height: | Size: 129 KiB |
BIN
src/assets/image/t1.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
src/assets/image/t10.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
src/assets/image/t2.png
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
BIN
src/assets/image/t3.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
src/assets/image/t4.png
Normal file
|
After Width: | Height: | Size: 3.2 KiB |
BIN
src/assets/image/t5.png
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
BIN
src/assets/image/t6.png
Normal file
|
After Width: | Height: | Size: 597 B |
BIN
src/assets/image/t7.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
src/assets/image/t8.png
Normal file
|
After Width: | Height: | Size: 2.0 KiB |
BIN
src/assets/image/t9.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
src/assets/image/time.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
src/assets/image/top_right.png
Normal file
|
After Width: | Height: | Size: 4.3 KiB |
BIN
src/assets/image/waterTempDown.png
Normal file
|
After Width: | Height: | Size: 34 KiB |
BIN
src/assets/image/waterTempUp.png
Normal file
|
After Width: | Height: | Size: 29 KiB |
22
src/index.css
Normal file
@@ -0,0 +1,22 @@
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen",
|
||||
"Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
|
||||
sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
code {
|
||||
font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New",
|
||||
monospace;
|
||||
}
|
||||
.error-page {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: white;
|
||||
}
|
||||
21
src/index.tsx
Normal file
@@ -0,0 +1,21 @@
|
||||
import React from "react";
|
||||
import ReactDOM from "react-dom/client";
|
||||
import "./index.css";
|
||||
import App from "./App";
|
||||
import reportWebVitals from "./reportWebVitals";
|
||||
|
||||
import { store } from "./store/store";
|
||||
import { Provider } from "react-redux";
|
||||
import UpdateData from "./store/UpdateData";
|
||||
|
||||
const root = ReactDOM.createRoot(
|
||||
document.getElementById("root") as HTMLElement
|
||||
);
|
||||
|
||||
root.render(
|
||||
<Provider store={store}>
|
||||
<App />
|
||||
<UpdateData />
|
||||
</Provider>
|
||||
);
|
||||
reportWebVitals();
|
||||
1
src/logo.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 841.9 595.3"><g fill="#61DAFB"><path d="M666.3 296.5c0-32.5-40.7-63.3-103.1-82.4 14.4-63.6 8-114.2-20.2-130.4-6.5-3.8-14.1-5.6-22.4-5.6v22.3c4.6 0 8.3.9 11.4 2.6 13.6 7.8 19.5 37.5 14.9 75.7-1.1 9.4-2.9 19.3-5.1 29.4-19.6-4.8-41-8.5-63.5-10.9-13.5-18.5-27.5-35.3-41.6-50 32.6-30.3 63.2-46.9 84-46.9V78c-27.5 0-63.5 19.6-99.9 53.6-36.4-33.8-72.4-53.2-99.9-53.2v22.3c20.7 0 51.4 16.5 84 46.6-14 14.7-28 31.4-41.3 49.9-22.6 2.4-44 6.1-63.6 11-2.3-10-4-19.7-5.2-29-4.7-38.2 1.1-67.9 14.6-75.8 3-1.8 6.9-2.6 11.5-2.6V78.5c-8.4 0-16 1.8-22.6 5.6-28.1 16.2-34.4 66.7-19.9 130.1-62.2 19.2-102.7 49.9-102.7 82.3 0 32.5 40.7 63.3 103.1 82.4-14.4 63.6-8 114.2 20.2 130.4 6.5 3.8 14.1 5.6 22.5 5.6 27.5 0 63.5-19.6 99.9-53.6 36.4 33.8 72.4 53.2 99.9 53.2 8.4 0 16-1.8 22.6-5.6 28.1-16.2 34.4-66.7 19.9-130.1 62-19.1 102.5-49.9 102.5-82.3zm-130.2-66.7c-3.7 12.9-8.3 26.2-13.5 39.5-4.1-8-8.4-16-13.1-24-4.6-8-9.5-15.8-14.4-23.4 14.2 2.1 27.9 4.7 41 7.9zm-45.8 106.5c-7.8 13.5-15.8 26.3-24.1 38.2-14.9 1.3-30 2-45.2 2-15.1 0-30.2-.7-45-1.9-8.3-11.9-16.4-24.6-24.2-38-7.6-13.1-14.5-26.4-20.8-39.8 6.2-13.4 13.2-26.8 20.7-39.9 7.8-13.5 15.8-26.3 24.1-38.2 14.9-1.3 30-2 45.2-2 15.1 0 30.2.7 45 1.9 8.3 11.9 16.4 24.6 24.2 38 7.6 13.1 14.5 26.4 20.8 39.8-6.3 13.4-13.2 26.8-20.7 39.9zm32.3-13c5.4 13.4 10 26.8 13.8 39.8-13.1 3.2-26.9 5.9-41.2 8 4.9-7.7 9.8-15.6 14.4-23.7 4.6-8 8.9-16.1 13-24.1zM421.2 430c-9.3-9.6-18.6-20.3-27.8-32 9 .4 18.2.7 27.5.7 9.4 0 18.7-.2 27.8-.7-9 11.7-18.3 22.4-27.5 32zm-74.4-58.9c-14.2-2.1-27.9-4.7-41-7.9 3.7-12.9 8.3-26.2 13.5-39.5 4.1 8 8.4 16 13.1 24 4.7 8 9.5 15.8 14.4 23.4zM420.7 163c9.3 9.6 18.6 20.3 27.8 32-9-.4-18.2-.7-27.5-.7-9.4 0-18.7.2-27.8.7 9-11.7 18.3-22.4 27.5-32zm-74 58.9c-4.9 7.7-9.8 15.6-14.4 23.7-4.6 8-8.9 16-13 24-5.4-13.4-10-26.8-13.8-39.8 13.1-3.1 26.9-5.8 41.2-7.9zm-90.5 125.2c-35.4-15.1-58.3-34.9-58.3-50.6 0-15.7 22.9-35.6 58.3-50.6 8.6-3.7 18-7 27.7-10.1 5.7 19.6 13.2 40 22.5 60.9-9.2 20.8-16.6 41.1-22.2 60.6-9.9-3.1-19.3-6.5-28-10.2zM310 490c-13.6-7.8-19.5-37.5-14.9-75.7 1.1-9.4 2.9-19.3 5.1-29.4 19.6 4.8 41 8.5 63.5 10.9 13.5 18.5 27.5 35.3 41.6 50-32.6 30.3-63.2 46.9-84 46.9-4.5-.1-8.3-1-11.3-2.7zm237.2-76.2c4.7 38.2-1.1 67.9-14.6 75.8-3 1.8-6.9 2.6-11.5 2.6-20.7 0-51.4-16.5-84-46.6 14-14.7 28-31.4 41.3-49.9 22.6-2.4 44-6.1 63.6-11 2.3 10.1 4.1 19.8 5.2 29.1zm38.5-66.7c-8.6 3.7-18 7-27.7 10.1-5.7-19.6-13.2-40-22.5-60.9 9.2-20.8 16.6-41.1 22.2-60.6 9.9 3.1 19.3 6.5 28.1 10.2 35.4 15.1 58.3 34.9 58.3 50.6-.1 15.7-23 35.6-58.4 50.6zM320.8 78.4z"/><circle cx="420.9" cy="296.5" r="45.7"/><path d="M520.5 78.1z"/></g></svg>
|
||||
|
After Width: | Height: | Size: 2.6 KiB |
45
src/page/Component/ScrollBoard/index.css
Normal file
@@ -0,0 +1,45 @@
|
||||
.dv-scroll-board {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
color: #fff;
|
||||
}
|
||||
.dv-scroll-board .text {
|
||||
padding: 0 10px;
|
||||
box-sizing: border-box;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
.dv-scroll-board .header {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
font-size: 15px;
|
||||
}
|
||||
.dv-scroll-board .header .header-item {
|
||||
transition: all 0.3s;
|
||||
padding: 0 10px;
|
||||
box-sizing: border-box;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
.dv-scroll-board .rows {
|
||||
overflow: hidden;
|
||||
}
|
||||
.dv-scroll-board .rows .ceil {
|
||||
padding: 0 10px;
|
||||
box-sizing: border-box;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
.dv-scroll-board .rows .row-item {
|
||||
display: flex;
|
||||
font-size: 14px;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
.dv-scroll-board .rows .row-item .index {
|
||||
border-radius: 3px;
|
||||
padding: 0px 3px;
|
||||
}
|
||||
440
src/page/Component/ScrollBoard/index.tsx
Normal file
@@ -0,0 +1,440 @@
|
||||
import React, { useEffect, useState, useRef, useMemo, forwardRef } from "react";
|
||||
import useAutoResize from "./use/autoResize";
|
||||
import { deepMerge } from "./util";
|
||||
import { deepClone } from "./util/utils";
|
||||
import { co } from "./util";
|
||||
import classnames from "classnames";
|
||||
import "./index.css";
|
||||
import { current } from "@reduxjs/toolkit";
|
||||
interface ScrollBoardProps {
|
||||
config?: object;
|
||||
onClick?: () => void;
|
||||
onMouseOver?: () => void;
|
||||
className?: string;
|
||||
style?: object;
|
||||
}
|
||||
interface TaskType {
|
||||
end: () => void;
|
||||
pause: () => void;
|
||||
resume: () => void;
|
||||
}
|
||||
|
||||
const defaultConfig = {
|
||||
/**
|
||||
* @description Board header
|
||||
* @type {Array<String>}
|
||||
* @default header = []
|
||||
* @example header = ['column1', 'column2', 'column3']
|
||||
*/
|
||||
header: [],
|
||||
/**
|
||||
* @description Board data
|
||||
* @type {Array<Array>}
|
||||
* @default data = []
|
||||
*/
|
||||
data: [],
|
||||
/**
|
||||
* @description Row num
|
||||
* @type {Number}
|
||||
* @default rowNum = 5
|
||||
*/
|
||||
rowNum: 5,
|
||||
/**
|
||||
* @description Header background color
|
||||
* @type {String}
|
||||
* @default headerBGC = '#00BAFF'
|
||||
*/
|
||||
headerBGC: "#00BAFF",
|
||||
/**
|
||||
* @description Odd row background color
|
||||
* @type {String}
|
||||
* @default oddRowBGC = '#003B51'
|
||||
*/
|
||||
oddRowBGC: "#003B51",
|
||||
/**
|
||||
* @description Even row background color
|
||||
* @type {String}
|
||||
* @default evenRowBGC = '#003B51'
|
||||
*/
|
||||
evenRowBGC: "#0A2732",
|
||||
/**
|
||||
* @description Scroll wait time
|
||||
* @type {Number}
|
||||
* @default waitTime = 2000
|
||||
*/
|
||||
waitTime: 2000,
|
||||
/**
|
||||
* @description Header height
|
||||
* @type {Number}
|
||||
* @default headerHeight = 35
|
||||
*/
|
||||
headerHeight: 35,
|
||||
/**
|
||||
* @description Column width
|
||||
* @type {Array<Number>}
|
||||
* @default columnWidth = []
|
||||
*/
|
||||
columnWidth: [],
|
||||
/**
|
||||
* @description Column align
|
||||
* @type {Array<String>}
|
||||
* @default align = []
|
||||
* @example align = ['left', 'center', 'right']
|
||||
*/
|
||||
align: [],
|
||||
/**
|
||||
* @description Show index
|
||||
* @type {Boolean}
|
||||
* @default index = false
|
||||
*/
|
||||
index: false,
|
||||
/**
|
||||
* @description index Header
|
||||
* @type {String}
|
||||
* @default indexHeader = '#'
|
||||
*/
|
||||
indexHeader: "#",
|
||||
/**
|
||||
* @description Carousel type
|
||||
* @type {String}
|
||||
* @default carousel = 'single'
|
||||
* @example carousel = 'single' | 'page'
|
||||
*/
|
||||
carousel: "single",
|
||||
/**
|
||||
* @description Pause scroll when mouse hovered
|
||||
* @type {Boolean}
|
||||
* @default hoverPause = true
|
||||
* @example hoverPause = true | false
|
||||
*/
|
||||
hoverPause: true,
|
||||
};
|
||||
function calcHeaderData({ header, index, indexHeader }: any) {
|
||||
if (!header.length) {
|
||||
return [];
|
||||
}
|
||||
|
||||
header = [...header];
|
||||
|
||||
if (index) header.unshift(indexHeader);
|
||||
|
||||
return header;
|
||||
}
|
||||
function calcRows({ data, index, headerBGC, rowNum }: any) {
|
||||
if (index) {
|
||||
data = data.map((row: any, i: any) => {
|
||||
row = [...row];
|
||||
|
||||
const indexTag = `<span class="index" style="background-color: ${headerBGC};">${
|
||||
i + 1
|
||||
}</span>`;
|
||||
|
||||
row.unshift(indexTag);
|
||||
|
||||
return row;
|
||||
});
|
||||
}
|
||||
|
||||
data = data.map((ceils: any, i: any) => ({ ceils, rowIndex: i }));
|
||||
|
||||
const rowLength = data.length;
|
||||
|
||||
if (rowLength > rowNum && rowLength < 2 * rowNum) {
|
||||
data = [...data, ...data];
|
||||
}
|
||||
|
||||
return data.map((d: any, i: any) => ({ ...d, scroll: i }));
|
||||
}
|
||||
function calcAligns(mergedConfig: any, header: any) {
|
||||
const columnNum = header.length;
|
||||
|
||||
let aligns = new Array(columnNum).fill("left");
|
||||
|
||||
const { align } = mergedConfig;
|
||||
|
||||
return deepMerge(aligns, align);
|
||||
}
|
||||
const ScrollBoard = forwardRef(
|
||||
(
|
||||
{ config, onClick, onMouseOver, className, style }: ScrollBoardProps,
|
||||
ref
|
||||
) => {
|
||||
const { width, height, domRef } = useAutoResize(ref);
|
||||
const [state, setState] = useState({
|
||||
mergedConfig: {
|
||||
align: [],
|
||||
carousel: "",
|
||||
columnWidth: [],
|
||||
data: [],
|
||||
evenRowBGC: "",
|
||||
header: [],
|
||||
headerBGC: "",
|
||||
headerHeight: 35,
|
||||
hoverPause: true,
|
||||
index: false,
|
||||
oddRowBGC: "",
|
||||
indexHeader: "#",
|
||||
rowNum: 5,
|
||||
waitTime: 2000,
|
||||
},
|
||||
header: [],
|
||||
rows: [],
|
||||
widths: [],
|
||||
heights: [],
|
||||
aligns: [],
|
||||
});
|
||||
const { mergedConfig, header, rows, widths, heights, aligns } = state;
|
||||
const stateRef = useRef({
|
||||
...state,
|
||||
rowsData: [],
|
||||
avgHeight: 0,
|
||||
animationIndex: 0,
|
||||
});
|
||||
Object.assign(stateRef.current, state);
|
||||
function onResize() {
|
||||
if (!mergedConfig) return;
|
||||
|
||||
const widths = calcWidths(mergedConfig, stateRef.current.rowsData);
|
||||
|
||||
const heights = calcHeights(mergedConfig, header);
|
||||
|
||||
const data: any = { widths, heights };
|
||||
|
||||
Object.assign(stateRef.current, data);
|
||||
setState((state) => ({ ...state, ...data }));
|
||||
}
|
||||
function calcData() {
|
||||
const mergedConfig = deepMerge(
|
||||
// deepClone(defaultConfig, true),
|
||||
deepClone(defaultConfig),
|
||||
config || {}
|
||||
);
|
||||
|
||||
const header = calcHeaderData(mergedConfig);
|
||||
|
||||
const rows = calcRows(mergedConfig);
|
||||
|
||||
const widths = calcWidths(mergedConfig, stateRef.current.rowsData);
|
||||
|
||||
const heights = calcHeights(mergedConfig, header);
|
||||
|
||||
const aligns = calcAligns(mergedConfig, header);
|
||||
|
||||
const data: any = {
|
||||
mergedConfig,
|
||||
header,
|
||||
rows,
|
||||
widths,
|
||||
aligns,
|
||||
heights,
|
||||
};
|
||||
|
||||
Object.assign(stateRef.current, data, {
|
||||
rowsData: rows,
|
||||
animationIndex: 0,
|
||||
});
|
||||
|
||||
setState((state) => ({ ...state, ...data }));
|
||||
}
|
||||
|
||||
function calcWidths({ columnWidth, header }: any, rowsData: any) {
|
||||
const usedWidth = columnWidth.reduce((all: any, w: any) => all + w, 0);
|
||||
|
||||
let columnNum = 0;
|
||||
if (rowsData[0]) {
|
||||
columnNum = rowsData[0].ceils.length;
|
||||
} else if (header.length) {
|
||||
columnNum = header.length;
|
||||
}
|
||||
|
||||
const avgWidth = (width - usedWidth) / (columnNum - columnWidth.length);
|
||||
|
||||
const widths = new Array(columnNum).fill(avgWidth);
|
||||
|
||||
return deepMerge(widths, columnWidth);
|
||||
}
|
||||
function calcHeights({ headerHeight, rowNum, data }: any, header: any) {
|
||||
let allHeight = height;
|
||||
|
||||
if (header.length) allHeight -= headerHeight;
|
||||
|
||||
const avgHeight = allHeight / rowNum;
|
||||
|
||||
Object.assign(stateRef.current, { avgHeight });
|
||||
|
||||
return new Array(data.length).fill(avgHeight);
|
||||
}
|
||||
function* animation(
|
||||
start = false
|
||||
): Generator<Promise<void>, void, unknown> {
|
||||
let {
|
||||
avgHeight,
|
||||
animationIndex,
|
||||
mergedConfig: { waitTime, carousel, rowNum },
|
||||
rowsData,
|
||||
} = stateRef.current;
|
||||
const rowLength = rowsData.length;
|
||||
|
||||
if (start) yield new Promise((resolve) => setTimeout(resolve, waitTime));
|
||||
|
||||
const animationNum = carousel === "single" ? 1 : rowNum;
|
||||
|
||||
let rows: any = rowsData.slice(animationIndex);
|
||||
rows.push(...rowsData.slice(0, animationIndex));
|
||||
rows = rows.slice(0, carousel === "page" ? rowNum * 2 : rowNum + 1);
|
||||
|
||||
const heights: any = new Array(rowLength).fill(avgHeight);
|
||||
setState((state) => ({ ...state, rows, heights }));
|
||||
|
||||
yield new Promise((resolve) => setTimeout(resolve, 300));
|
||||
|
||||
animationIndex += animationNum;
|
||||
|
||||
const back = animationIndex - rowLength;
|
||||
if (back >= 0) animationIndex = back;
|
||||
|
||||
const newHeights: any = [...heights];
|
||||
newHeights.splice(0, animationNum, ...new Array(animationNum).fill(0));
|
||||
|
||||
Object.assign(stateRef.current, { animationIndex });
|
||||
setState((state) => ({ ...state, heights: newHeights }));
|
||||
}
|
||||
function emitEvent(handle: any, ri: any, ci: any, row: any, ceil: any) {
|
||||
const { ceils, rowIndex } = row;
|
||||
|
||||
handle && handle({ row: ceils, ceil, rowIndex, columnIndex: ci });
|
||||
}
|
||||
|
||||
function handleHover(
|
||||
enter: any,
|
||||
ri?: any,
|
||||
ci?: any,
|
||||
row?: any,
|
||||
ceil?: any
|
||||
) {
|
||||
if (enter) emitEvent(onMouseOver, ri, ci, row, ceil);
|
||||
|
||||
if (!mergedConfig.hoverPause) return;
|
||||
|
||||
if (task.current) {
|
||||
const { pause, resume } = task.current;
|
||||
|
||||
enter
|
||||
? (function () {
|
||||
if (pause) pause();
|
||||
})()
|
||||
: (function () {
|
||||
if (resume) resume();
|
||||
})();
|
||||
}
|
||||
}
|
||||
|
||||
const getBackgroundColor = (rowIndex: any) =>
|
||||
mergedConfig[rowIndex % 2 === 0 ? "evenRowBGC" : "oddRowBGC"];
|
||||
|
||||
const task = useRef<TaskType>(null);
|
||||
|
||||
useEffect(() => {
|
||||
calcData();
|
||||
|
||||
let start = true;
|
||||
|
||||
function* loop() {
|
||||
while (true) {
|
||||
yield* animation(start);
|
||||
|
||||
start = false;
|
||||
|
||||
const { waitTime } = stateRef.current.mergedConfig;
|
||||
|
||||
yield new Promise((resolve) => setTimeout(resolve, waitTime - 300));
|
||||
}
|
||||
}
|
||||
|
||||
const {
|
||||
mergedConfig: { rowNum },
|
||||
rows: rowsData,
|
||||
} = stateRef.current;
|
||||
|
||||
const rowLength = rowsData.length;
|
||||
if (rowNum >= rowLength) return;
|
||||
// @ts-ignore
|
||||
task.current = co(loop);
|
||||
if (task.current) {
|
||||
return task.current.end;
|
||||
}
|
||||
}, [config, domRef.current]);
|
||||
|
||||
useEffect(onResize, [width, height, domRef.current]);
|
||||
|
||||
const classNames = useMemo(
|
||||
() => classnames("dv-scroll-board", className),
|
||||
[className]
|
||||
);
|
||||
|
||||
return (
|
||||
<div className={classNames} style={style} ref={domRef}>
|
||||
{!!header.length && !!mergedConfig && (
|
||||
<div
|
||||
className="header"
|
||||
style={{ backgroundColor: `${mergedConfig.headerBGC}` }}
|
||||
>
|
||||
{header.map((headerItem, i) => (
|
||||
<div
|
||||
className="header-item"
|
||||
key={`${headerItem}-${i}`}
|
||||
style={{
|
||||
height: `${mergedConfig.headerHeight}px`,
|
||||
lineHeight: `${mergedConfig.headerHeight}px`,
|
||||
width: `${widths[i]}px`,
|
||||
}}
|
||||
// @ts-ignore
|
||||
align={aligns[i]}
|
||||
dangerouslySetInnerHTML={{ __html: headerItem }}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{!!mergedConfig && (
|
||||
<div
|
||||
className="rows"
|
||||
style={{
|
||||
height: `${
|
||||
height - (header.length ? mergedConfig.headerHeight : 0)
|
||||
}px`,
|
||||
}}
|
||||
>
|
||||
{rows.map((row: any, ri) => (
|
||||
<div
|
||||
className="row-item"
|
||||
key={`${row.toString()}-${row.scroll}`}
|
||||
style={{
|
||||
height: `${heights[ri]}px`,
|
||||
lineHeight: `${heights[ri]}px`,
|
||||
backgroundColor: `${getBackgroundColor(row.rowIndex)}`,
|
||||
}}
|
||||
>
|
||||
{row.ceils.map((ceil: any, ci: any) => (
|
||||
<div
|
||||
className="ceil"
|
||||
key={`${ceil}-${ri}-${ci}`}
|
||||
style={{ width: `${widths[ci]}px` }}
|
||||
// @ts-ignore
|
||||
align={aligns[ci]}
|
||||
dangerouslySetInnerHTML={{ __html: ceil }}
|
||||
onClick={() => emitEvent(onClick, ri, ci, row, ceil)}
|
||||
onMouseEnter={() => handleHover(true, ri, ci, row, ceil)}
|
||||
onMouseLeave={() => handleHover(false)}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
export default ScrollBoard;
|
||||
57
src/page/Component/ScrollBoard/use/autoResize.ts
Normal file
@@ -0,0 +1,57 @@
|
||||
import {
|
||||
useState,
|
||||
useCallback,
|
||||
useEffect,
|
||||
useRef,
|
||||
useImperativeHandle,
|
||||
} from "react";
|
||||
import { debounce, observerDomResize } from "../util/index";
|
||||
|
||||
export default function useAutoResize(ref: any) {
|
||||
const [state, setState] = useState({ width: 0, height: 0 });
|
||||
|
||||
const domRef = useRef(null);
|
||||
|
||||
const setWH = useCallback(() => {
|
||||
const { clientWidth, clientHeight } = domRef.current || {
|
||||
clientWidth: 0,
|
||||
clientHeight: 0,
|
||||
};
|
||||
|
||||
setState({ width: clientWidth, height: clientHeight });
|
||||
|
||||
if (!domRef.current) {
|
||||
console.warn(
|
||||
"DataV: Failed to get dom node, component rendering may be abnormal!"
|
||||
);
|
||||
} else if (!clientWidth || !clientHeight) {
|
||||
console.warn(
|
||||
"DataV: Component width or height is 0px, rendering abnormality may occur!"
|
||||
);
|
||||
}
|
||||
}, []);
|
||||
|
||||
useImperativeHandle(ref, () => ({ setWH }), []);
|
||||
|
||||
useEffect(() => {
|
||||
const debounceSetWHFun = debounce(setWH, 100);
|
||||
|
||||
debounceSetWHFun();
|
||||
const domObserver = observerDomResize(domRef.current, debounceSetWHFun);
|
||||
|
||||
window.addEventListener("resize", debounceSetWHFun);
|
||||
|
||||
return () => {
|
||||
window.removeEventListener("resize", debounceSetWHFun);
|
||||
|
||||
if (!domObserver) {
|
||||
return;
|
||||
}
|
||||
|
||||
domObserver.disconnect();
|
||||
domObserver.takeRecords();
|
||||
};
|
||||
}, []);
|
||||
|
||||
return { ...state, domRef, setWH };
|
||||
}
|
||||
57
src/page/Component/ScrollBoard/use/autoResize1.js
Normal file
@@ -0,0 +1,57 @@
|
||||
import {
|
||||
useState,
|
||||
useCallback,
|
||||
useEffect,
|
||||
useRef,
|
||||
useImperativeHandle,
|
||||
} from "react";
|
||||
import { debounce, observerDomResize } from "../util/index";
|
||||
|
||||
export default function useAutoResize(ref) {
|
||||
const [state, setState] = useState({ width: 0, height: 0 });
|
||||
|
||||
const domRef = useRef(null);
|
||||
|
||||
const setWH = useCallback(() => {
|
||||
const { clientWidth, clientHeight } = domRef.current || {
|
||||
clientWidth: 0,
|
||||
clientHeight: 0,
|
||||
};
|
||||
|
||||
setState({ width: clientWidth, height: clientHeight });
|
||||
|
||||
if (!domRef.current) {
|
||||
console.warn(
|
||||
"DataV: Failed to get dom node, component rendering may be abnormal!"
|
||||
);
|
||||
} else if (!clientWidth || !clientHeight) {
|
||||
console.warn(
|
||||
"DataV: Component width or height is 0px, rendering abnormality may occur!"
|
||||
);
|
||||
}
|
||||
}, []);
|
||||
|
||||
useImperativeHandle(ref, () => ({ setWH }), []);
|
||||
|
||||
useEffect(() => {
|
||||
const debounceSetWHFun = debounce(setWH, 100);
|
||||
|
||||
debounceSetWHFun();
|
||||
const domObserver = observerDomResize(domRef.current, debounceSetWHFun);
|
||||
|
||||
window.addEventListener("resize", debounceSetWHFun);
|
||||
|
||||
return () => {
|
||||
window.removeEventListener("resize", debounceSetWHFun);
|
||||
|
||||
if (!domObserver) {
|
||||
return;
|
||||
}
|
||||
|
||||
domObserver.disconnect();
|
||||
domObserver.takeRecords();
|
||||
};
|
||||
}, []);
|
||||
|
||||
return { ...state, domRef, setWH };
|
||||
}
|
||||
114
src/page/Component/ScrollBoard/util/index.ts
Normal file
@@ -0,0 +1,114 @@
|
||||
export function co(gen: any) {
|
||||
let destroyed = false;
|
||||
|
||||
// 处理 return 之后 resume 的问题
|
||||
let stop = false;
|
||||
|
||||
let val: any = null;
|
||||
|
||||
if (typeof gen === "function") gen = gen();
|
||||
|
||||
if (!gen || typeof gen.next !== "function") return () => ({});
|
||||
|
||||
Promise.resolve().then(() => {
|
||||
destroyed || next(gen.next());
|
||||
});
|
||||
|
||||
return {
|
||||
end() {
|
||||
destroyed = true;
|
||||
|
||||
Promise.resolve().then(() => {
|
||||
gen.return();
|
||||
|
||||
gen = null;
|
||||
});
|
||||
},
|
||||
pause() {
|
||||
if (!destroyed) {
|
||||
stop = true;
|
||||
}
|
||||
},
|
||||
resume() {
|
||||
const oldVal = val;
|
||||
|
||||
if (!destroyed && stop) {
|
||||
stop = false;
|
||||
|
||||
Promise.resolve(val).then(function () {
|
||||
if (!destroyed && !stop && oldVal === val) {
|
||||
next(gen.next());
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
function next(ret: any) {
|
||||
if (ret.done) return ret.value;
|
||||
|
||||
val = ret.value;
|
||||
|
||||
return Promise.resolve(ret.value).then(() => {
|
||||
!destroyed && !stop && next(gen.next());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 将函数转成防抖动函数
|
||||
* @param {Function} 需要转成防抖动函数的函数
|
||||
* @param {number} 延迟时间(毫秒数)
|
||||
* @param {boolean} 是否执行第一次
|
||||
* @return {undefined} 无返回值
|
||||
*/
|
||||
export function debounce(fn: any, delay = 600, runFirstFn = true) {
|
||||
let timer: any = null;
|
||||
|
||||
return function (this: any, ...rest: any) {
|
||||
// 清除定时器
|
||||
clearTimeout(timer);
|
||||
if (runFirstFn) {
|
||||
fn.apply(this, rest);
|
||||
runFirstFn = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// 设置定时器
|
||||
timer = setTimeout(fn.bind(this, ...rest), delay);
|
||||
};
|
||||
}
|
||||
export function observerDomResize(dom: any, callback: any) {
|
||||
const MutationObserver = window.MutationObserver;
|
||||
// window.WebKitMutationObserver ||
|
||||
// window.MozMutationObserver;
|
||||
|
||||
const observer = new MutationObserver(callback);
|
||||
|
||||
observer.observe(dom, {
|
||||
attributes: true,
|
||||
attributeFilter: ["style"],
|
||||
attributeOldValue: true,
|
||||
});
|
||||
return observer;
|
||||
}
|
||||
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
||||
var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof"));
|
||||
var _util = require("./../util/utils");
|
||||
export function deepMerge(target: any, merged: any) {
|
||||
for (var key in merged) {
|
||||
if (target[key] && _typeof2["default"](target[key]) === "object") {
|
||||
deepMerge(target[key], merged[key]);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (_typeof2["default"](merged[key]) === "object") {
|
||||
target[key] = _util.deepClone(merged[key], true);
|
||||
continue;
|
||||
}
|
||||
|
||||
target[key] = merged[key];
|
||||
}
|
||||
|
||||
return target;
|
||||
}
|
||||
32
src/page/Component/ScrollBoard/util/utils.ts
Normal file
@@ -0,0 +1,32 @@
|
||||
/**
|
||||
* @description Clone an object or array
|
||||
* @param {Object|Array} object Cloned object
|
||||
* @param {Boolean} recursion Whether to use recursive cloning
|
||||
* @return {Object|Array} Clone object
|
||||
*/
|
||||
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
||||
var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof"));
|
||||
export function deepClone(object: any) {
|
||||
var recursion =
|
||||
arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
||||
if (!object) return object;
|
||||
var parse = JSON.parse,
|
||||
stringify = JSON.stringify;
|
||||
if (!recursion) return parse(stringify(object));
|
||||
var clonedObj: any = object instanceof Array ? [] : {};
|
||||
|
||||
if (object && _typeof2["default"](object) === "object") {
|
||||
for (var key in object) {
|
||||
if (object.hasOwnProperty(key)) {
|
||||
if (object[key] && _typeof2["default"](object[key]) === "object") {
|
||||
// clonedObj[key] = deepClone(object[key], true);
|
||||
clonedObj[key] = deepClone(object[key]);
|
||||
} else {
|
||||
clonedObj[key] = object[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return clonedObj;
|
||||
}
|
||||
30
src/page/Component/TopTitle/index.css
Normal file
@@ -0,0 +1,30 @@
|
||||
.top_block {
|
||||
width: 5760px;
|
||||
height: 186px;
|
||||
background-image: url(/public/image/topTitle.png);
|
||||
background-size:5760px;
|
||||
position: relative;
|
||||
font-weight: 500;
|
||||
font-size: 26px;
|
||||
color: #51f0ff;
|
||||
}
|
||||
.top_center__title {
|
||||
position: absolute;
|
||||
left: 2234px;
|
||||
top: 30px;
|
||||
font-weight: 500;
|
||||
font-size: 73px;
|
||||
color: #6BF2FF;
|
||||
letter-spacing: 22px;
|
||||
text-shadow: 0px 0px 8px rgba(221,237,255,0.34);
|
||||
}
|
||||
.top_right__title {
|
||||
font-size: 36px;
|
||||
position: absolute;
|
||||
right: 1253px;
|
||||
top:112px;
|
||||
}
|
||||
.time {
|
||||
display: inline-block;
|
||||
margin-left: 45px;
|
||||
}
|
||||
31
src/page/Component/TopTitle/index.tsx
Normal file
@@ -0,0 +1,31 @@
|
||||
import "./index.css";
|
||||
import moment from "moment";
|
||||
import "moment/locale/zh-cn";
|
||||
import { useState, useEffect } from "react";
|
||||
import img1 from './../../../assets/image/top_right.png'
|
||||
function TopTitle() {
|
||||
const [date, setDate] = useState<string>(moment().format("YYYY.MM.DD"));
|
||||
const [week, setWeek] = useState<string>(
|
||||
moment().locale("zh-cn").format("dddd")
|
||||
);
|
||||
const [time, setTime] = useState<string>(moment().format("HH:mm:ss"));
|
||||
useEffect(() => {
|
||||
const timer = setInterval(() => {
|
||||
setDate(moment().format("YYYY.MM.DD"));
|
||||
setWeek(moment().locale("zh-cn").format("dddd"));
|
||||
setTime(moment().format("HH:mm:ss"));
|
||||
}, 1000);
|
||||
return () => clearInterval(timer);
|
||||
}, []);
|
||||
return (
|
||||
<div className="top_block">
|
||||
<div className="top_center__title">河北德金集团数据智慧指挥中心</div>
|
||||
<img src={img1} alt="" style={{position:'absolute',width:'870px',right:'1054px',top:'128px'}}/>
|
||||
<div className="top_right__title">
|
||||
{date}
|
||||
{week} <span className="time">{time}</span>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
export default TopTitle;
|
||||
12
src/page/ErrorPage.tsx
Normal file
@@ -0,0 +1,12 @@
|
||||
import "./../index.css";
|
||||
|
||||
function ErrorPage() {
|
||||
return (
|
||||
<div className="error-page">
|
||||
<h1>Oops!</h1>
|
||||
<p>Sorry, an unexpected error has occurred.</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default ErrorPage;
|
||||
52
src/page/HomePage/Center/BPress/index.tsx
Normal file
@@ -0,0 +1,52 @@
|
||||
import ReactECharts from "echarts-for-react";
|
||||
import TitleBox from "../../Component/TitleBox";
|
||||
import { useAppSelector } from "../../../../store/hooks";
|
||||
import { selectLineChart } from "../../../../store/HomePageSlice";
|
||||
import getOptions from "../../Component/LineChartRed/chart.config";
|
||||
import { generateTimeLabels } from "../../../../utils"
|
||||
function BPress() {
|
||||
const data = useAppSelector(selectLineChart).鼓泡系统温度TE361 || [];
|
||||
let xData: any = [];
|
||||
let line6: Number[] = [];
|
||||
let yName = "单位/℃";
|
||||
if (data.length !== 0) {
|
||||
xData = generateTimeLabels(data.length)
|
||||
line6 = data
|
||||
}else{
|
||||
xData = [];
|
||||
line6 = [];
|
||||
}
|
||||
const options= getOptions(xData, line6, yName);
|
||||
return (
|
||||
<div className="center_down">
|
||||
<TitleBox title="bpress" />
|
||||
<div className="legend_right">
|
||||
<span className="dot" style={{background: '#18C7F3'}}></span>
|
||||
<span>六线</span>
|
||||
{/* <span className="dot" style={{background: '#F31868'}}></span>
|
||||
<span>五线</span> */}
|
||||
</div>
|
||||
{
|
||||
options && (
|
||||
<div className="chart_blur_bg">
|
||||
<ReactECharts option={options} style={{ height: "100%" }} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
{!options && (
|
||||
<p
|
||||
style={{
|
||||
color: "#cccf",
|
||||
fontSize: "24px",
|
||||
userSelect: "none",
|
||||
textAlign: "center",
|
||||
paddingTop: "72px",
|
||||
}}
|
||||
>
|
||||
暂无数据
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
export default BPress;
|
||||
52
src/page/HomePage/Center/BWater/index.tsx
Normal file
@@ -0,0 +1,52 @@
|
||||
import ReactECharts from "echarts-for-react";
|
||||
import TitleBox from "../../Component/TitleBox";
|
||||
import { useAppSelector } from "../../../../store/hooks";
|
||||
import { selectLineChart } from "../../../../store/HomePageSlice";
|
||||
import getOptions from "../../Component/LineChartRed/chart.config";
|
||||
import { generateTimeLabels } from "../../../../utils"
|
||||
function BWater() {
|
||||
const data = useAppSelector(selectLineChart).天然气总管流量 || [];
|
||||
let xData: any = [];
|
||||
let line6: Number[] = [];
|
||||
let yName = "单位/m³";
|
||||
if (data.length !== 0) {
|
||||
xData = generateTimeLabels(data.length)
|
||||
line6 = data
|
||||
}else{
|
||||
xData = [];
|
||||
line6 = [];
|
||||
}
|
||||
const options= getOptions(xData, line6, yName);
|
||||
return (
|
||||
<div className="center_down">
|
||||
<TitleBox title="bwater" />
|
||||
<div className="legend_right">
|
||||
<span className="dot" style={{background: '#18C7F3'}}></span>
|
||||
<span>六线</span>
|
||||
{/* <span className="dot" style={{background: '#F31868'}}></span>
|
||||
<span>五线</span> */}
|
||||
</div>
|
||||
{
|
||||
options && (
|
||||
<div className="chart_blur_bg">
|
||||
<ReactECharts option={options} style={{ height: "100%" }} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
{!options && (
|
||||
<p
|
||||
style={{
|
||||
color: "#cccf",
|
||||
fontSize: "24px",
|
||||
userSelect: "none",
|
||||
textAlign: "center",
|
||||
paddingTop: "72px",
|
||||
}}
|
||||
>
|
||||
暂无数据
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
export default BWater;
|
||||
34
src/page/HomePage/Center/Center.tsx
Normal file
@@ -0,0 +1,34 @@
|
||||
|
||||
import Nitrogen from "./Nitrogen"
|
||||
import Oxygen from "./Oxygen"
|
||||
import HydrogenGas from "./HydrogenGas"
|
||||
import KPress from "./KPress"
|
||||
import KTemp from "./KTemp"
|
||||
import WPress from "./WPress"
|
||||
import BWater from "./BWater"
|
||||
import FlowTemp from "./FlowTemp"
|
||||
import BPress from "./BPress"
|
||||
import RecWaterPress from "./RecWaterPress"
|
||||
import CenterTop from "./CenterTop"
|
||||
function Center() {
|
||||
return (
|
||||
<div>
|
||||
<div className="center_up_box">
|
||||
<CenterTop />
|
||||
</div>
|
||||
<div className="center_down_box flex-row">
|
||||
<Nitrogen />
|
||||
<Oxygen />
|
||||
<HydrogenGas />
|
||||
<KPress />
|
||||
<KTemp />
|
||||
<WPress />
|
||||
<BWater />
|
||||
<FlowTemp />
|
||||
<BPress />
|
||||
<RecWaterPress />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
export default Center;
|
||||
108
src/page/HomePage/Center/CenterTop/index.tsx
Normal file
@@ -0,0 +1,108 @@
|
||||
import img1 from './../../../../assets/image/fire.png'
|
||||
import img2 from './../../../../assets/image/change_fire.png'
|
||||
import img3 from './../../../../assets/image/time.png'
|
||||
import eqicon1 from './../../../../assets/image/eq_icon1.png'
|
||||
import eqicon2 from './../../../../assets/image/eq_icon2.png'
|
||||
import eqicon3 from './../../../../assets/image/eq_icon3.png'
|
||||
import eqicon4 from './../../../../assets/image/eq_icon4.png'
|
||||
import { useAppSelector } from "../../../../store/hooks";
|
||||
import { selectOther } from "../../../../store/HomePageSlice";
|
||||
|
||||
function CenterTop() {
|
||||
const fireData = useAppSelector(selectOther).火向 || '-';
|
||||
const timeData = useAppSelector(selectOther).换火时间 || '-';
|
||||
const reTime = useAppSelector(selectOther).剩余换火时间 || '-';
|
||||
return (
|
||||
<div className="center_up">
|
||||
<div className="center_up_top1">
|
||||
<img src={img1} alt="" style={{width:'71px',position:'absolute',left:'40px',top:'25px'}}/>
|
||||
<div className='center_up_top1_text'>
|
||||
<div className='center_up_top1_text_left'>
|
||||
<p style={{fontSize:'27px',color:'rgba(255, 255, 255, 0.90)'}}>六线火向</p>
|
||||
<p style={{fontSize:'47px',textAlign:'center'}}>{fireData}</p>
|
||||
</div>
|
||||
<span className='center_up_top_text_split'></span>
|
||||
<div>
|
||||
<p style={{fontSize:'27px',color:'rgba(255, 255, 255, 0.90)'}}>五线火向</p>
|
||||
<p style={{fontSize:'47px',textAlign:'center'}}>-</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="center_up_top2">
|
||||
<img src={img2} alt="" style={{width:'71px',position:'absolute',left:'40px',top:'25px'}}/>
|
||||
<div className='center_up_top2_text'>
|
||||
<div className='center_up_top2_text_left'>
|
||||
<p style={{fontSize:'27px',color:'rgba(255, 255, 255, 0.90)'}}>六线换火时间</p>
|
||||
<p style={{fontSize:'47px',textAlign:'center'}}>{timeData}</p>
|
||||
</div>
|
||||
<span className='center_up_top_text_split'></span>
|
||||
<div>
|
||||
<p style={{fontSize:'27px',color:'rgba(255, 255, 255, 0.90)'}}>五线换火时间</p>
|
||||
<p style={{fontSize:'47px',textAlign:'center'}}>-</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="center_up_top2" style={{left:'2534px'}}>
|
||||
<img src={img3} alt="" style={{width:'71px',position:'absolute',left:'40px',top:'25px'}}/>
|
||||
<div className='center_up_top2_text'>
|
||||
<div className='center_up_top2_text_left'>
|
||||
<p style={{fontSize:'27px',color:'rgba(255, 255, 255, 0.90)'}}>六线.剩余时间</p>
|
||||
<p style={{fontSize:'47px',textAlign:'center'}}>{reTime}</p>
|
||||
</div>
|
||||
<span className='center_up_top_text_split'></span>
|
||||
<div>
|
||||
<p style={{fontSize:'27px',color:'rgba(255, 255, 255, 0.90)'}}>五线.剩余时间</p>
|
||||
<p style={{fontSize:'47px',textAlign:'center'}}>-</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div className='line_up'>
|
||||
<img src={eqicon2} alt="" style={{width:'57px',height:'51px',position:'absolute',left:'90px',top:'3px'}}/>
|
||||
<img src={eqicon2} alt="" style={{width:'57px',height:'51px',position:'absolute',left:'775px',top:'14px'}}/>
|
||||
<img src={eqicon1} alt="" style={{width:'57px',height:'51px',position:'absolute',left:'-11px',bottom:'63px'}}/>
|
||||
<img src={eqicon1} alt="" style={{width:'57px',height:'51px',position:'absolute',left:'692px',bottom:'52px'}}/>
|
||||
{/* <div className='eqbg2' style={{left:'540px',top:'-34px'}}>
|
||||
<p className='eqbg_text'>卡脖1</p>
|
||||
<p className='eqbg_num'>99.9℃</p>
|
||||
</div>
|
||||
<div className='eqbg2' style={{left:'953px',top:'-17px'}}>
|
||||
<p className='eqbg_text'>鼓泡1</p>
|
||||
<p className='eqbg_num'>99.9℃</p>
|
||||
</div>
|
||||
<div className='eqbg1' style={{left:'420px',bottom:'26px'}}>
|
||||
<p className='eqbg_text'>卡脖1</p>
|
||||
<p className='eqbg_num'>99.9℃</p>
|
||||
</div>
|
||||
<div className='eqbg1' style={{left:'840px',bottom:'26px'}}>
|
||||
<p className='eqbg_text'>鼓泡1</p>
|
||||
<p className='eqbg_num'>99.9℃</p>
|
||||
</div> */}
|
||||
</div>
|
||||
<div className='line_down'>
|
||||
<img src={eqicon2} alt="" style={{width:'57px',height:'51px',position:'absolute',left:'90px',top:'3px'}}/>
|
||||
<img src={eqicon2} alt="" style={{width:'57px',height:'51px',position:'absolute',left:'775px',top:'14px'}}/>
|
||||
<img src={eqicon1} alt="" style={{width:'57px',height:'51px',position:'absolute',left:'-11px',bottom:'63px'}}/>
|
||||
<img src={eqicon1} alt="" style={{width:'57px',height:'51px',position:'absolute',left:'692px',bottom:'52px'}}/>
|
||||
{/* <div className='eqbg2' style={{left:'580px',top:'-34px'}}>
|
||||
<p className='eqbg_text'>卡脖1</p>
|
||||
<p className='eqbg_num'>99.9℃</p>
|
||||
</div>
|
||||
<div className='eqbg2' style={{left:'953px',top:'-17px'}}>
|
||||
<p className='eqbg_text'>鼓泡1</p>
|
||||
<p className='eqbg_num'>99.9℃</p>
|
||||
</div>
|
||||
<div className='eqbg1' style={{left:'420px',bottom:'26px'}}>
|
||||
<p className='eqbg_text'>卡脖1</p>
|
||||
<p className='eqbg_num'>99.9℃</p>
|
||||
</div>
|
||||
<div className='eqbg1' style={{left:'840px',bottom:'26px'}}>
|
||||
<p className='eqbg_text'>鼓泡1</p>
|
||||
<p className='eqbg_num'>99.9℃</p>
|
||||
</div> */}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export default CenterTop;
|
||||
52
src/page/HomePage/Center/FlowTemp/index.tsx
Normal file
@@ -0,0 +1,52 @@
|
||||
import ReactECharts from "echarts-for-react";
|
||||
import TitleBox from "../../Component/TitleBox";
|
||||
import { useAppSelector } from "../../../../store/hooks";
|
||||
import { selectLineChart } from "../../../../store/HomePageSlice";
|
||||
import getOptions from "../../Component/LineChartYellow/chart.config";
|
||||
import { generateTimeLabels } from "../../../../utils"
|
||||
function FlowTemp() {
|
||||
const data = useAppSelector(selectLineChart).流道温度 || [];
|
||||
let xData: any = [];
|
||||
let line6: Number[] = [];
|
||||
let yName = "单位/℃";
|
||||
if (data.length !== 0) {
|
||||
xData = generateTimeLabels(data.length)
|
||||
line6 = data
|
||||
}else{
|
||||
xData = [];
|
||||
line6 = [];
|
||||
}
|
||||
const options= getOptions(xData, line6, yName);
|
||||
return (
|
||||
<div className="center_down">
|
||||
<TitleBox title="flow_temp" />
|
||||
<div className="legend_right">
|
||||
<span className="dot" style={{background: '#FFD160'}}></span>
|
||||
<span>六线</span>
|
||||
{/* <span className="dot" style={{background: '#2760FF'}}></span>
|
||||
<span>五线</span> */}
|
||||
</div>
|
||||
{
|
||||
options && (
|
||||
<div className="chart_blur_bg">
|
||||
<ReactECharts option={options} style={{ height: "100%" }} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
{!options && (
|
||||
<p
|
||||
style={{
|
||||
color: "#cccf",
|
||||
fontSize: "24px",
|
||||
userSelect: "none",
|
||||
textAlign: "center",
|
||||
paddingTop: "72px",
|
||||
}}
|
||||
>
|
||||
暂无数据
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
export default FlowTemp;
|
||||
75
src/page/HomePage/Center/HydrogenGas/index.tsx
Normal file
@@ -0,0 +1,75 @@
|
||||
import ReactECharts from "echarts-for-react";
|
||||
import TitleBox from "../../Component/TitleBox";
|
||||
import { useAppSelector } from "../../../../store/hooks";
|
||||
import { selectLineChart } from "../../../../store/HomePageSlice";
|
||||
import getOptions from "../../Component/LineChartRedDob/chart.config";
|
||||
import { generateTimeLabels } from "../../../../utils";
|
||||
function HydrogenGas() {
|
||||
const data61 = useAppSelector(selectLineChart)['1#氢气流量'] || [];
|
||||
const data62 = useAppSelector(selectLineChart)['2#氢气流量'] || [];
|
||||
let xData: any = [];
|
||||
let yName = "单位/m³";
|
||||
let seriesData: any = [
|
||||
{
|
||||
name: "六线1",
|
||||
data: [],
|
||||
},
|
||||
{
|
||||
name: "六线2",
|
||||
data: [],
|
||||
}
|
||||
];
|
||||
if (data61.length !== 0) {
|
||||
xData = generateTimeLabels(data61.length)
|
||||
seriesData[0].data = data61
|
||||
}else{
|
||||
seriesData[0].data = [];
|
||||
if (data62.length !== 0) {
|
||||
xData = generateTimeLabels(data62.length)
|
||||
}else{
|
||||
xData = [];
|
||||
}
|
||||
}
|
||||
if (data62.length !== 0) {
|
||||
seriesData[1].data = data62
|
||||
}else{
|
||||
seriesData[1].data = [];
|
||||
}
|
||||
const options = getOptions(xData, seriesData, yName);
|
||||
return (
|
||||
<div className="center_down">
|
||||
<TitleBox title="hydrogen_gas" />
|
||||
<div className="legend_right">
|
||||
<span className="dot" style={{background: '#18C7F3'}}></span>
|
||||
<span>六线1</span>
|
||||
<span className="dot" style={{background: '#2665FE',marginLeft: '8px'}}></span>
|
||||
<span>六线2</span>
|
||||
{/* <span className="dot" style={{background: '#E718F3',marginLeft: '8px'}}></span>
|
||||
<span>五线1</span>
|
||||
<span className="dot" style={{background: '#F31868',marginLeft: '8px'}}></span>
|
||||
<span>五线2</span> */}
|
||||
</div>
|
||||
{
|
||||
options && (
|
||||
<div className="chart_blur_bg">
|
||||
<ReactECharts option={options} style={{ height: "100%" }} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
{!options && (
|
||||
<p
|
||||
style={{
|
||||
color: "#cccf",
|
||||
fontSize: "24px",
|
||||
userSelect: "none",
|
||||
textAlign: "center",
|
||||
paddingTop: "72px",
|
||||
}}
|
||||
>
|
||||
暂无数据
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
export default HydrogenGas;
|
||||
52
src/page/HomePage/Center/KPress/index.tsx
Normal file
@@ -0,0 +1,52 @@
|
||||
import ReactECharts from "echarts-for-react";
|
||||
import TitleBox from "../../Component/TitleBox";
|
||||
import { useAppSelector } from "../../../../store/hooks";
|
||||
import { selectLineChart } from "../../../../store/HomePageSlice";
|
||||
import getOptions from "../../Component/LineChartYellow/chart.config";
|
||||
import { generateTimeLabels } from "../../../../utils"
|
||||
function KPress() {
|
||||
const data = useAppSelector(selectLineChart).熔窑压力 || [];
|
||||
let xData: any = [];
|
||||
let line6: Number[] = [];
|
||||
let yName = "单位/Kpa";
|
||||
if (data.length !== 0) {
|
||||
xData = generateTimeLabels(data.length)
|
||||
line6 = data
|
||||
}else{
|
||||
xData = [];
|
||||
line6 = [];
|
||||
}
|
||||
const options= getOptions(xData, line6, yName);
|
||||
return (
|
||||
<div className="center_down">
|
||||
<TitleBox title="kpress" />
|
||||
<div className="legend_right">
|
||||
<span className="dot" style={{background: '#FFD160'}}></span>
|
||||
<span>六线</span>
|
||||
{/* <span className="dot" style={{background: '#2760FF'}}></span>
|
||||
<span>五线</span> */}
|
||||
</div>
|
||||
{
|
||||
options && (
|
||||
<div className="chart_blur_bg">
|
||||
<ReactECharts option={options} style={{ height: "100%" }} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
{!options && (
|
||||
<p
|
||||
style={{
|
||||
color: "#cccf",
|
||||
fontSize: "24px",
|
||||
userSelect: "none",
|
||||
textAlign: "center",
|
||||
paddingTop: "72px",
|
||||
}}
|
||||
>
|
||||
暂无数据
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
export default KPress;
|
||||
52
src/page/HomePage/Center/KTemp/index.tsx
Normal file
@@ -0,0 +1,52 @@
|
||||
import ReactECharts from "echarts-for-react";
|
||||
import TitleBox from "../../Component/TitleBox";
|
||||
import { useAppSelector } from "../../../../store/hooks";
|
||||
import { selectLineChart } from "../../../../store/HomePageSlice";
|
||||
import getOptions from "../../Component/LineChartRed/chart.config";
|
||||
import { generateTimeLabels } from "../../../../utils"
|
||||
function KTemp() {
|
||||
const data = useAppSelector(selectLineChart).熔窑温度 || [];
|
||||
let xData: any = [];
|
||||
let line6: Number[] = [];
|
||||
let yName = "单位/℃";
|
||||
if (data.length !== 0) {
|
||||
xData = generateTimeLabels(data.length)
|
||||
line6 = data
|
||||
}else{
|
||||
xData = [];
|
||||
line6 = [];
|
||||
}
|
||||
const options= getOptions(xData, line6, yName);
|
||||
return (
|
||||
<div className="center_down">
|
||||
<TitleBox title="ktemp" />
|
||||
<div className="legend_right">
|
||||
<span className="dot" style={{background: '#18C7F3'}}></span>
|
||||
<span>六线</span>
|
||||
{/* <span className="dot" style={{background: '#F31868'}}></span>
|
||||
<span>五线</span> */}
|
||||
</div>
|
||||
{
|
||||
options && (
|
||||
<div className="chart_blur_bg">
|
||||
<ReactECharts option={options} style={{ height: "100%" }} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
{!options && (
|
||||
<p
|
||||
style={{
|
||||
color: "#cccf",
|
||||
fontSize: "24px",
|
||||
userSelect: "none",
|
||||
textAlign: "center",
|
||||
paddingTop: "72px",
|
||||
}}
|
||||
>
|
||||
暂无数据
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
export default KTemp;
|
||||
75
src/page/HomePage/Center/Nitrogen/index.tsx
Normal file
@@ -0,0 +1,75 @@
|
||||
import ReactECharts from "echarts-for-react";
|
||||
import TitleBox from "../../Component/TitleBox";
|
||||
import { useAppSelector } from "../../../../store/hooks";
|
||||
import { selectLineChart } from "../../../../store/HomePageSlice";
|
||||
import getOptions from "../../Component/LineChartRedDob/chart.config";
|
||||
import { generateTimeLabels } from "../../../../utils";
|
||||
function Nitrogen() {
|
||||
const data61 = useAppSelector(selectLineChart)['1#氮气流量'] || [];
|
||||
const data62 = useAppSelector(selectLineChart)['2#氮气流量'] || [];
|
||||
let xData: any = [];
|
||||
let yName = "单位/m³";
|
||||
let seriesData: any = [
|
||||
{
|
||||
name: "六线1",
|
||||
data: [],
|
||||
},
|
||||
{
|
||||
name: "六线2",
|
||||
data: [],
|
||||
}
|
||||
];
|
||||
if (data61.length !== 0) {
|
||||
xData = generateTimeLabels(data61.length)
|
||||
seriesData[0].data = data61
|
||||
}else{
|
||||
seriesData[0].data = [];
|
||||
if (data62.length !== 0) {
|
||||
xData = generateTimeLabels(data62.length)
|
||||
}else{
|
||||
xData = [];
|
||||
}
|
||||
}
|
||||
if (data62.length !== 0) {
|
||||
seriesData[1].data = data62
|
||||
}else{
|
||||
seriesData[1].data = [];
|
||||
}
|
||||
const options = getOptions(xData, seriesData, yName);
|
||||
return (
|
||||
<div className="center_down">
|
||||
<TitleBox title="nitrogen" />
|
||||
<div className="legend_right">
|
||||
<span className="dot" style={{background: '#18C7F3'}}></span>
|
||||
<span>六线1</span>
|
||||
<span className="dot" style={{background: '#2665FE',marginLeft: '8px'}}></span>
|
||||
<span>六线2</span>
|
||||
{/* <span className="dot" style={{background: '#E718F3',marginLeft: '8px'}}></span>
|
||||
<span>五线1</span>
|
||||
<span className="dot" style={{background: '#F31868',marginLeft: '8px'}}></span>
|
||||
<span>五线2</span> */}
|
||||
</div>
|
||||
{
|
||||
options && (
|
||||
<div className="chart_blur_bg">
|
||||
<ReactECharts option={options} style={{ height: "100%" }} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
{!options && (
|
||||
<p
|
||||
style={{
|
||||
color: "#cccf",
|
||||
fontSize: "24px",
|
||||
userSelect: "none",
|
||||
textAlign: "center",
|
||||
paddingTop: "72px",
|
||||
}}
|
||||
>
|
||||
暂无数据
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
export default Nitrogen;
|
||||
75
src/page/HomePage/Center/Oxygen/index.tsx
Normal file
@@ -0,0 +1,75 @@
|
||||
import ReactECharts from "echarts-for-react";
|
||||
import TitleBox from "../../Component/TitleBox";
|
||||
import { useAppSelector } from "../../../../store/hooks";
|
||||
import { selectLineChart } from "../../../../store/HomePageSlice";
|
||||
import getOptions from "../../Component/LineChartRedDob/chart.config";
|
||||
import { generateTimeLabels } from "../../../../utils";
|
||||
function Oxygen() {
|
||||
const data61 = useAppSelector(selectLineChart)['0#氧枪左氧气流量'] || [];
|
||||
const data62 = useAppSelector(selectLineChart)['0#氧枪右氧气流量'] || [];
|
||||
let xData: any = [];
|
||||
let yName = "单位/m³";
|
||||
let seriesData: any = [
|
||||
{
|
||||
name: "六线左氧",
|
||||
data: [],
|
||||
},
|
||||
{
|
||||
name: "六线右氧",
|
||||
data: [],
|
||||
}
|
||||
];
|
||||
if (data61.length !== 0) {
|
||||
xData = generateTimeLabels(data61.length)
|
||||
seriesData[0].data = data61
|
||||
}else{
|
||||
seriesData[0].data = [];
|
||||
if (data62.length !== 0) {
|
||||
xData = generateTimeLabels(data62.length)
|
||||
}else{
|
||||
xData = [];
|
||||
}
|
||||
}
|
||||
if (data62.length !== 0) {
|
||||
seriesData[1].data = data62
|
||||
}else{
|
||||
seriesData[1].data = [];
|
||||
}
|
||||
const options = getOptions(xData, seriesData, yName);
|
||||
return (
|
||||
<div className="center_down">
|
||||
<TitleBox title="oxygen" />
|
||||
<div className="legend_right">
|
||||
<span className="dot" style={{background: '#18C7F3'}}></span>
|
||||
<span>六线左氧</span>
|
||||
<span className="dot" style={{background: '#2665FE',marginLeft: '8px'}}></span>
|
||||
<span>六线右氧</span>
|
||||
{/* <span className="dot" style={{background: '#E718F3',marginLeft: '8px'}}></span>
|
||||
<span>五线1</span>
|
||||
<span className="dot" style={{background: '#F31868',marginLeft: '8px'}}></span>
|
||||
<span>五线2</span> */}
|
||||
</div>
|
||||
{
|
||||
options && (
|
||||
<div className="chart_blur_bg">
|
||||
<ReactECharts option={options} style={{ height: "100%" }} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
{!options && (
|
||||
<p
|
||||
style={{
|
||||
color: "#cccf",
|
||||
fontSize: "24px",
|
||||
userSelect: "none",
|
||||
textAlign: "center",
|
||||
paddingTop: "72px",
|
||||
}}
|
||||
>
|
||||
暂无数据
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
export default Oxygen;
|
||||
52
src/page/HomePage/Center/RecWaterPress/index.tsx
Normal file
@@ -0,0 +1,52 @@
|
||||
import ReactECharts from "echarts-for-react";
|
||||
import TitleBox from "../../Component/TitleBox";
|
||||
import { useAppSelector } from "../../../../store/hooks";
|
||||
import { selectLineChart } from "../../../../store/HomePageSlice";
|
||||
import getOptions from "../../Component/LineChartYellow/chart.config";
|
||||
import { generateTimeLabels } from "../../../../utils"
|
||||
function RecWaterPress() {
|
||||
const data = useAppSelector(selectLineChart).水循环温度 || [];
|
||||
let xData: any = [];
|
||||
let line6: Number[] = [];
|
||||
let yName = "单位/℃";
|
||||
if (data.length !== 0) {
|
||||
xData = generateTimeLabels(data.length)
|
||||
line6 = data
|
||||
}else{
|
||||
xData = [];
|
||||
line6 = [];
|
||||
}
|
||||
const options= getOptions(xData, line6, yName);
|
||||
return (
|
||||
<div className="center_down">
|
||||
<TitleBox title="rec_water_press" />
|
||||
<div className="legend_right">
|
||||
<span className="dot" style={{background: '#FFD160'}}></span>
|
||||
<span>六线</span>
|
||||
{/* <span className="dot" style={{background: '#2760FF'}}></span>
|
||||
<span>五线</span> */}
|
||||
</div>
|
||||
{
|
||||
options && (
|
||||
<div className="chart_blur_bg">
|
||||
<ReactECharts option={options} style={{ height: "100%" }} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
{!options && (
|
||||
<p
|
||||
style={{
|
||||
color: "#cccf",
|
||||
fontSize: "24px",
|
||||
userSelect: "none",
|
||||
textAlign: "center",
|
||||
paddingTop: "72px",
|
||||
}}
|
||||
>
|
||||
暂无数据
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
export default RecWaterPress;
|
||||
52
src/page/HomePage/Center/WPress/index.tsx
Normal file
@@ -0,0 +1,52 @@
|
||||
import ReactECharts from "echarts-for-react";
|
||||
import TitleBox from "../../Component/TitleBox";
|
||||
import { useAppSelector } from "../../../../store/hooks";
|
||||
import { selectLineChart } from "../../../../store/HomePageSlice";
|
||||
import getOptions from "../../Component/LineChartYellow/chart.config";
|
||||
import { generateTimeLabels } from "../../../../utils"
|
||||
function WPress() {
|
||||
const data = useAppSelector(selectLineChart).总管冷却水压力 || [];
|
||||
let xData: any = [];
|
||||
let line6: Number[] = [];
|
||||
let yName = "单位/Kpa";
|
||||
if (data.length !== 0) {
|
||||
xData = generateTimeLabels(data.length)
|
||||
line6 = data
|
||||
}else{
|
||||
xData = [];
|
||||
line6 = [];
|
||||
}
|
||||
const options= getOptions(xData, line6, yName);
|
||||
return (
|
||||
<div className="center_down">
|
||||
<TitleBox title="wpress" />
|
||||
<div className="legend_right">
|
||||
<span className="dot" style={{background: '#FFD160'}}></span>
|
||||
<span>六线</span>
|
||||
{/* <span className="dot" style={{background: '#2760FF'}}></span>
|
||||
<span>五线</span> */}
|
||||
</div>
|
||||
{
|
||||
options && (
|
||||
<div className="chart_blur_bg">
|
||||
<ReactECharts option={options} style={{ height: "100%" }} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
{!options && (
|
||||
<p
|
||||
style={{
|
||||
color: "#cccf",
|
||||
fontSize: "24px",
|
||||
userSelect: "none",
|
||||
textAlign: "center",
|
||||
paddingTop: "72px",
|
||||
}}
|
||||
>
|
||||
暂无数据
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
export default WPress;
|
||||
96
src/page/HomePage/Component/LineChartRed/chart.config.ts
Normal file
@@ -0,0 +1,96 @@
|
||||
import * as echarts from "echarts";
|
||||
export default function getOptions(xData: any, line6: any, yName: string) {
|
||||
if (xData.length === 0 || line6.length === 0)
|
||||
return null;
|
||||
return {
|
||||
grid: { top: 30, right: 0, bottom: 0, left: 10,containLabel: true},
|
||||
legend: {
|
||||
show:false
|
||||
},
|
||||
xAxis: {
|
||||
type: "category",
|
||||
data: xData,
|
||||
axisLabel: {
|
||||
color: "rgba(223, 241, 254, 0.8)",
|
||||
fontSize: 12,
|
||||
interval: 'auto',
|
||||
rotate:30,
|
||||
},
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
width: 1,
|
||||
color: "rgba(69, 97, 174, 1)",
|
||||
},
|
||||
},
|
||||
},
|
||||
yAxis:{
|
||||
name: yName,
|
||||
nameTextStyle: {
|
||||
color: "rgba(223, 241, 254, 0.8)",
|
||||
fontSize: 12,
|
||||
align: "center",
|
||||
},
|
||||
type: "value",
|
||||
alignTicks: true,
|
||||
axisLabel: {
|
||||
color: "rgba(223, 241, 254, 0.65)",
|
||||
fontSize: 12,
|
||||
formatter: "{value}",
|
||||
},
|
||||
axisLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
width: 1,
|
||||
color: "rgba(69, 97, 174, 1)",
|
||||
},
|
||||
},
|
||||
splitLine: {
|
||||
lineStyle: {
|
||||
width: 1,
|
||||
color: "rgba(69, 97, 174, 1)",
|
||||
},
|
||||
},
|
||||
},
|
||||
tooltip: {
|
||||
trigger: "axis",
|
||||
axisPointer: {
|
||||
type: "shadow",
|
||||
},
|
||||
className: "dejin-chart-tooltip",
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name:'六线',
|
||||
data: line6,
|
||||
color: "rgba(24, 199, 243, 1)",
|
||||
type: "line",
|
||||
symbol: "circle",
|
||||
symbolSize: 6,
|
||||
areaStyle: {
|
||||
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
||||
{ offset: 0, color: "rgba(24, 199, 243, 0.6)" },
|
||||
{ offset: 0.4, color: "rgba(24, 199, 243, 0.1)" },
|
||||
{ offset: 0.8, color: "rgba(24, 199, 243, 0)" },
|
||||
{ offset: 1, color: "rgba(24, 199, 243, 0)" },
|
||||
]),
|
||||
},
|
||||
},
|
||||
// {
|
||||
// name:'五线',
|
||||
// data: line5,
|
||||
// color: "rgba(243, 24, 104, 1)",
|
||||
// type: "line",
|
||||
// symbol: "circle",
|
||||
// symbolSize: 6,
|
||||
// areaStyle: {
|
||||
// color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
||||
// { offset: 0, color: "rgba(243, 24, 104, 0.6)" },
|
||||
// { offset: 0.4, color: "rgba(243, 24, 104, 0.1)" },
|
||||
// { offset: 0.8, color: "rgba(243, 24, 104, 0)" },
|
||||
// { offset: 1, color: "rgba(243, 24, 104, 0)" },
|
||||
// ]),
|
||||
// },
|
||||
// },
|
||||
],
|
||||
};
|
||||
}
|
||||
112
src/page/HomePage/Component/LineChartRedDob/chart.config.ts
Normal file
@@ -0,0 +1,112 @@
|
||||
import * as echarts from "echarts";
|
||||
export default function getOptions(xData: any, seriesData: any, yName: string) {
|
||||
if (xData.length === 0)
|
||||
return null;
|
||||
return {
|
||||
grid: { top: 30, right: 0, bottom: 0, left: 10,containLabel: true},
|
||||
legend: {
|
||||
show:false
|
||||
},
|
||||
xAxis: {
|
||||
type: "category",
|
||||
data: xData,
|
||||
axisLabel: {
|
||||
color: "rgba(223, 241, 254, 0.8)",
|
||||
fontSize: 12,
|
||||
interval: 'auto',
|
||||
rotate:30,
|
||||
},
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
width: 1,
|
||||
color: "rgba(69, 97, 174, 1)",
|
||||
},
|
||||
},
|
||||
},
|
||||
yAxis:{
|
||||
name: yName,
|
||||
nameTextStyle: {
|
||||
color: "rgba(223, 241, 254, 0.8)",
|
||||
fontSize: 12,
|
||||
align: "center",
|
||||
},
|
||||
type: "value",
|
||||
alignTicks: true,
|
||||
axisLabel: {
|
||||
color: "rgba(223, 241, 254, 0.65)",
|
||||
fontSize: 12,
|
||||
formatter: "{value}",
|
||||
},
|
||||
axisLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
width: 1,
|
||||
color: "rgba(69, 97, 174, 1)",
|
||||
},
|
||||
},
|
||||
splitLine: {
|
||||
lineStyle: {
|
||||
width: 1,
|
||||
color: "rgba(69, 97, 174, 1)",
|
||||
},
|
||||
},
|
||||
},
|
||||
tooltip: {
|
||||
trigger: "axis",
|
||||
axisPointer: {
|
||||
type: "shadow",
|
||||
},
|
||||
className: "dejin-chart-tooltip",
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name:seriesData[0].name,
|
||||
data: seriesData[0].data,
|
||||
color: "rgba(24, 199, 243, 1)",
|
||||
type: "line",
|
||||
symbol: "circle",
|
||||
symbolSize: 6,
|
||||
areaStyle: {
|
||||
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
||||
{ offset: 0, color: "rgba(24, 199, 243, 0.6)" },
|
||||
{ offset: 0.4, color: "rgba(24, 199, 243, 0.1)" },
|
||||
{ offset: 0.8, color: "rgba(24, 199, 243, 0)" },
|
||||
{ offset: 1, color: "rgba(24, 199, 243, 0)" },
|
||||
]),
|
||||
},
|
||||
},
|
||||
{
|
||||
name:seriesData[1].name,
|
||||
data: seriesData[1].data,
|
||||
color: "rgba(38, 101, 254, 1)",
|
||||
type: "line",
|
||||
symbol: "circle",
|
||||
symbolSize: 6,
|
||||
areaStyle: {
|
||||
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
||||
{ offset: 0, color: "rgba(38, 101, 254, 0.6)" },
|
||||
{ offset: 0.4, color: "rgba(38, 101, 254, 0.1)" },
|
||||
{ offset: 0.8, color: "rgba(38, 101, 254, 0)" },
|
||||
{ offset: 1, color: "rgba(38, 101, 254, 0)" },
|
||||
]),
|
||||
},
|
||||
},
|
||||
// {
|
||||
// name:'五线',
|
||||
// data: line5,
|
||||
// color: "rgba(243, 24, 104, 1)",
|
||||
// type: "line",
|
||||
// symbol: "circle",
|
||||
// symbolSize: 6,
|
||||
// areaStyle: {
|
||||
// color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
||||
// { offset: 0, color: "rgba(243, 24, 104, 0.6)" },
|
||||
// { offset: 0.4, color: "rgba(243, 24, 104, 0.1)" },
|
||||
// { offset: 0.8, color: "rgba(243, 24, 104, 0)" },
|
||||
// { offset: 1, color: "rgba(243, 24, 104, 0)" },
|
||||
// ]),
|
||||
// },
|
||||
// },
|
||||
],
|
||||
};
|
||||
}
|
||||
96
src/page/HomePage/Component/LineChartYellow/chart.config.ts
Normal file
@@ -0,0 +1,96 @@
|
||||
import * as echarts from "echarts";
|
||||
export default function getOptions(xData: any, line6: any, yName: string) {
|
||||
if (xData.length === 0 || line6.length === 0)
|
||||
return null;
|
||||
return {
|
||||
grid: { top: 30, right: 0, bottom: 0, left: 10,containLabel: true},
|
||||
legend: {
|
||||
show:false
|
||||
},
|
||||
xAxis: {
|
||||
type: "category",
|
||||
data: xData,
|
||||
axisLabel: {
|
||||
color: "rgba(223, 241, 254, 0.8)",
|
||||
fontSize: 12,
|
||||
interval: 'auto',
|
||||
rotate:30,
|
||||
},
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
width: 1,
|
||||
color: "rgba(69, 97, 174, 1)",
|
||||
},
|
||||
},
|
||||
},
|
||||
yAxis:{
|
||||
name: yName,
|
||||
nameTextStyle: {
|
||||
color: "rgba(223, 241, 254, 0.8)",
|
||||
fontSize: 12,
|
||||
align: "center",
|
||||
},
|
||||
type: "value",
|
||||
alignTicks: true,
|
||||
axisLabel: {
|
||||
color: "rgba(223, 241, 254, 0.65)",
|
||||
fontSize: 12,
|
||||
formatter: "{value}",
|
||||
},
|
||||
axisLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
width: 1,
|
||||
color: "rgba(69, 97, 174, 1)",
|
||||
},
|
||||
},
|
||||
splitLine: {
|
||||
lineStyle: {
|
||||
width: 1,
|
||||
color: "rgba(69, 97, 174, 1)",
|
||||
},
|
||||
},
|
||||
},
|
||||
tooltip: {
|
||||
trigger: "axis",
|
||||
axisPointer: {
|
||||
type: "shadow",
|
||||
},
|
||||
className: "dejin-chart-tooltip",
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name:'六线',
|
||||
data: line6,
|
||||
color: "rgba(255, 209, 96, 1)",
|
||||
type: "line",
|
||||
symbol: "circle",
|
||||
symbolSize: 6,
|
||||
areaStyle: {
|
||||
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
||||
{ offset: 0, color: "rgba(255, 209, 96, 0.6)" },
|
||||
{ offset: 0.4, color: "rgba(255, 209, 96, 0.1)" },
|
||||
{ offset: 0.8, color: "rgba(255, 209, 96, 0)" },
|
||||
{ offset: 1, color: "rgba(255, 209, 96, 0)" },
|
||||
]),
|
||||
},
|
||||
},
|
||||
// {
|
||||
// name:'五线',
|
||||
// data: line5,
|
||||
// color: "rgba(39, 96, 255, 1)",
|
||||
// type: "line",
|
||||
// symbol: "circle",
|
||||
// symbolSize: 6,
|
||||
// areaStyle: {
|
||||
// color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
||||
// { offset: 0, color: "rgba(39, 96, 255, 0.6)" },
|
||||
// { offset: 0.4, color: "rgba(39, 96, 255, 0.1)" },
|
||||
// { offset: 0.8, color: "rgba(39, 96, 255, 0)" },
|
||||
// { offset: 1, color: "rgba(39, 96, 255, 0)" },
|
||||
// ]),
|
||||
// },
|
||||
// },
|
||||
],
|
||||
};
|
||||
}
|
||||
26
src/page/HomePage/Component/Rectangle/index.css
Normal file
@@ -0,0 +1,26 @@
|
||||
.rectangle_box {
|
||||
width: 246px;
|
||||
height: 70px;
|
||||
line-height: 70px;
|
||||
background: url(../../../../../public/image/homePage/b1.png) no-repeat;
|
||||
background-size: 100% 100%;
|
||||
background-position: 0 0;
|
||||
font-family: PingFangSC, PingFang SC;
|
||||
color: rgba(255, 255, 255, 0.9);
|
||||
font-size: 15px;
|
||||
letter-spacing: 1px;
|
||||
font-weight: 500;
|
||||
}
|
||||
.rectangle_box img {
|
||||
width: 32px;
|
||||
height: 34px;
|
||||
position: relative;
|
||||
top: 10px;
|
||||
margin: 0 8px 0 20px;
|
||||
}
|
||||
.rectangle_box .title {
|
||||
display: inline-block;
|
||||
width: 120px;
|
||||
padding-right: 5px;
|
||||
text-align: right;
|
||||
}
|
||||
16
src/page/HomePage/Component/Rectangle/index.tsx
Normal file
@@ -0,0 +1,16 @@
|
||||
import "./index.css";
|
||||
interface RectangleProps {
|
||||
name: string;
|
||||
rate: string;
|
||||
icon: number;
|
||||
}
|
||||
function Rectangle(props: RectangleProps) {
|
||||
return (
|
||||
<div className="rectangle_box">
|
||||
<img src={require(`./../../../../assets/image/icon${props.icon}.png`)} />
|
||||
<span className="title">{props.name}:</span>
|
||||
<span>{props.rate}</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
export default Rectangle;
|
||||
21
src/page/HomePage/Component/Rectangle2/index.css
Normal file
@@ -0,0 +1,21 @@
|
||||
.rectangle2 {
|
||||
width: 245px;
|
||||
height: 41px;
|
||||
line-height: 41px;
|
||||
background: url(../../../../../public/image/homePage/b2.png) no-repeat;
|
||||
background-size: 100% 100%;
|
||||
background-position: 0 0;
|
||||
font-family: PingFangSC, PingFang SC;
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
font-size: 16px;
|
||||
letter-spacing: 2px;
|
||||
font-weight: 500;
|
||||
}
|
||||
.rectangle2_title {
|
||||
display: inline-block;
|
||||
width: 160px;
|
||||
text-align: right;
|
||||
}
|
||||
.rectangle2_content {
|
||||
display: inline-block;
|
||||
}
|
||||
16
src/page/HomePage/Component/Rectangle2/index.tsx
Normal file
@@ -0,0 +1,16 @@
|
||||
import "./index.css";
|
||||
interface Props {
|
||||
name: string;
|
||||
value: string;
|
||||
}
|
||||
function Rectangle2(props: Props) {
|
||||
return (
|
||||
<div className="rectangle2">
|
||||
<div>
|
||||
<span className="rectangle2_title">{props.name}:</span>
|
||||
<span className="rectangle2_content">{props.value}</span>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
export default Rectangle2;
|
||||
14
src/page/HomePage/Component/TitleBox/index.css
Normal file
@@ -0,0 +1,14 @@
|
||||
.title_box {
|
||||
font-family: PingFangSC, PingFang SC;
|
||||
font-size: 24px;
|
||||
color: #72F2FF;
|
||||
font-weight: 400;
|
||||
}
|
||||
.title_box img {
|
||||
width: 25px;
|
||||
height: 25px;
|
||||
vertical-align: bottom;
|
||||
margin-right: 8px;
|
||||
position: relative;
|
||||
top: -2px;
|
||||
}
|
||||
122
src/page/HomePage/Component/TitleBox/index.tsx
Normal file
@@ -0,0 +1,122 @@
|
||||
import t1 from "./../../../../assets/image/t1.png";
|
||||
import t2 from "./../../../../assets/image/t2.png";
|
||||
import t3 from "./../../../../assets/image/t3.png";
|
||||
import t4 from "./../../../../assets/image/t4.png";
|
||||
import t5 from "./../../../../assets/image/t5.png";
|
||||
import t6 from "./../../../../assets/image/t6.png";
|
||||
import t7 from "./../../../../assets/image/t7.png";
|
||||
import t8 from "./../../../../assets/image/t8.png";
|
||||
import t9 from "./../../../../assets/image/t9.png";
|
||||
import t10 from "./../../../../assets/image/t10.png";
|
||||
import "./index.css";
|
||||
interface titleProps {
|
||||
title: string;
|
||||
}
|
||||
function TitleBox(props: titleProps) {
|
||||
const filteredTitles = () => {
|
||||
switch (props.title) {
|
||||
case "running_time6":
|
||||
return {
|
||||
img: t1,
|
||||
title: <span>窑炉运行时间<span style={{display: 'inline-block',lineHeight: '23px',verticalAlign: 'top',margin: '0 5px'}}>.</span>六线</span>,
|
||||
};
|
||||
case "running_time5":
|
||||
return {
|
||||
img: t1,
|
||||
title: <span>窑炉运行时间<span style={{display: 'inline-block',lineHeight: '23px',verticalAlign: 'top',margin: '0 5px'}}>.</span>五线</span>,
|
||||
};
|
||||
case "pressure6":
|
||||
return {
|
||||
img: t2,
|
||||
title: <span>窑炉压力<span style={{display: 'inline-block',lineHeight: '23px',verticalAlign: 'top',margin: '0 5px'}}>.</span>六线</span>,
|
||||
};
|
||||
case "pressure5":
|
||||
return {
|
||||
img: t2,
|
||||
title: <span>窑炉压力<span style={{display: 'inline-block',lineHeight: '23px',verticalAlign: 'top',margin: '0 5px'}}>.</span>五线</span>,
|
||||
};
|
||||
case "water_temp6":
|
||||
return {
|
||||
img: t3,
|
||||
title: <span>窑炉进出口水温<span style={{display: 'inline-block',lineHeight: '23px',verticalAlign: 'top',margin: '0 5px'}}>.</span>六线</span>,
|
||||
};
|
||||
case "water_temp5":
|
||||
return {
|
||||
img: t3,
|
||||
title: <span>窑炉进出口水温<span style={{display: 'inline-block',lineHeight: '23px',verticalAlign: 'top',margin: '0 5px'}}>.</span>五线</span>,
|
||||
};
|
||||
case "fan_run6":
|
||||
return {
|
||||
img: t4,
|
||||
title: <span>风机运行情况<span style={{display: 'inline-block',lineHeight: '23px',verticalAlign: 'top',margin: '0 5px'}}>.</span>六线</span>,
|
||||
};
|
||||
case "fan_run5":
|
||||
return {
|
||||
img: t4,
|
||||
title: <span>风机运行情况<span style={{display: 'inline-block',lineHeight: '23px',verticalAlign: 'top',margin: '0 5px'}}>.</span>五线</span>,
|
||||
};
|
||||
case "nitrogen":
|
||||
return {
|
||||
img: t5,
|
||||
title: "氮气流量",
|
||||
};
|
||||
case "oxygen":
|
||||
return {
|
||||
img: t5,
|
||||
title: "氧气流量",
|
||||
};
|
||||
case "hydrogen_gas":
|
||||
return {
|
||||
img: t5,
|
||||
title: "氢气流量",
|
||||
};
|
||||
case "kpress":
|
||||
return {
|
||||
img: t6,
|
||||
title: "窑炉压力",
|
||||
};
|
||||
case "ktemp":
|
||||
return {
|
||||
img: t7,
|
||||
title: "窑炉温度",
|
||||
};
|
||||
case "wpress":
|
||||
return {
|
||||
img: t8,
|
||||
title: "总管冷却水压力",
|
||||
};
|
||||
case "bwater":
|
||||
return {
|
||||
img: t9,
|
||||
title: "天然气总管流量",
|
||||
};
|
||||
case "flow_temp":
|
||||
return {
|
||||
img: t7,
|
||||
title: "流道温度",
|
||||
};
|
||||
case "bpress":
|
||||
return {
|
||||
img: t8,
|
||||
title: "液面计冷却水温度",
|
||||
};
|
||||
case "rec_water_press":
|
||||
return {
|
||||
img: t10,
|
||||
title: "循环水温度",
|
||||
};
|
||||
default:
|
||||
return {
|
||||
img: t10,
|
||||
title: "循环水温度",
|
||||
};
|
||||
}
|
||||
};
|
||||
return (
|
||||
<div className="title_box">
|
||||
<img src={filteredTitles().img} alt="title" />
|
||||
<span>{filteredTitles().title}</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
export default TitleBox;
|
||||
40
src/page/HomePage/Left/LeftDown1/index.tsx
Normal file
@@ -0,0 +1,40 @@
|
||||
import TitleBox from "../../Component/TitleBox";
|
||||
import img1 from "../../../../assets/image/waterTempUp.png"
|
||||
// import img2 from "../../../../assets/image/waterTempDown.png"
|
||||
import { useAppSelector } from "../../../../store/hooks";
|
||||
import { selectOther } from "../../../../store/HomePageSlice";
|
||||
function LeftDown1() {
|
||||
const outputData = useAppSelector(selectOther).出口水温 || '';
|
||||
// 数字显示组件
|
||||
const DigitalDisplay = ({ value }:any) => {
|
||||
return (
|
||||
value.split('').map((char:any, index:any) => (
|
||||
char !== '.'? (
|
||||
<span key={index} className="left_down1_numbg">
|
||||
{char}
|
||||
</span>
|
||||
):(<span key={index} className="left_down1_dotted"></span>)
|
||||
))
|
||||
);
|
||||
};
|
||||
return (
|
||||
<div className="left_down1">
|
||||
<TitleBox title="water_temp6" />
|
||||
<div style={{position:'absolute',left:'45px',bottom:'100px'}}>
|
||||
{
|
||||
outputData === ''? (
|
||||
<>
|
||||
<span className="left_down1_numbg">-</span>
|
||||
<span className="left_down1_numbg">-</span>
|
||||
<span className="left_down1_numbg">-</span>
|
||||
</>
|
||||
):<DigitalDisplay value={outputData}/>
|
||||
}
|
||||
<span style={{fontSize:'30px',color:'#fff'}}>℃</span>
|
||||
</div>
|
||||
<div className="left_down1_tip" style={{bottom:'36px'}}>出口实时水温</div>
|
||||
<img src={img1} alt="" style={{position:'absolute',width:'139px',right:'68px',bottom:'36px'}}/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
export default LeftDown1;
|
||||
63
src/page/HomePage/Left/LeftDown2/index.tsx
Normal file
@@ -0,0 +1,63 @@
|
||||
import TitleBox from "../../Component/TitleBox";
|
||||
import ScrollBoard from "../../../Component/ScrollBoard";
|
||||
import { useAppSelector } from "../../../../store/hooks";
|
||||
import { selectFan } from "../../../../store/HomePageSlice";
|
||||
function LeftDown2() {
|
||||
const data = useAppSelector(selectFan).风机运行 || [];
|
||||
const config = {
|
||||
header: ["序号", "设备名称", "运行状态", "设备状态"],
|
||||
headerHeight: 30,
|
||||
rowNum: 5,
|
||||
headerBGC: "rgba(4, 74, 132, 0.2)",
|
||||
oddRowBGC: "rgba(4, 74, 132, 0.2)",
|
||||
evenRowBGC: "rgba(11, 84, 153, 0.36)",
|
||||
columnWidth: [90, 220, 110, 110],
|
||||
align: ["center", "left", "left", "center"],
|
||||
data:[]
|
||||
// data: [
|
||||
// ['1','产线1的名称','<span style=color:#fff>未运行</span>','<span style=color:#3984FF><span style=display:inline-block;width:7px;height:7px;border-radius:4px;background:#2760FF;vertical-align:middle;margin-right:5px;margin-bottom:5px;></span>正常</span>'],
|
||||
// ['2','产线1的名称','<span style=color:#30E89A>未运行</span>','<span style=color:#FF0C0C><span style=display:inline-block;width:7px;height:7px;border-radius:4px;background:#FF0C0C;vertical-align:middle;margin-right:5px;margin-bottom:5px;></span>故障</span>'],
|
||||
// ['3','产线1的名称','<span style=color:#fff>未运行</span>','<span style=color:#3984FF><span style=display:inline-block;width:7px;height:7px;border-radius:4px;background:#2760FF;vertical-align:middle;margin-right:5px;margin-bottom:5px;></span>正常</span>'],
|
||||
// ['4','产线1的名称','<span style=color:#30E89A>未运行</span>','<span style=color:#3984FF><span style=display:inline-block;width:7px;height:7px;border-radius:4px;background:#2760FF;vertical-align:middle;margin-right:5px;margin-bottom:5px;></span>正常</span>'],
|
||||
// ['5','产线1的名称','<span style=color:#fff>未运行</span>','<span style=color:#FF0C0C><span style=display:inline-block;width:7px;height:7px;border-radius:4px;background:#FF0C0C;vertical-align:middle;margin-right:5px;margin-bottom:5px;></span>故障</span>']
|
||||
// ],
|
||||
};
|
||||
let arr: any = [];
|
||||
data&&
|
||||
data.map((item: any, index: any) => {
|
||||
let arrInner = [];
|
||||
arrInner.push(
|
||||
index + 1,
|
||||
item[0],
|
||||
index%2 === 0 ? `<span style=color:#fff>${item[1]}</span>`:`<span style=color:#30E89A>${item[1]}</span>`,
|
||||
item[2]==='正常'?`<span style=color:#3984FF><span style=display:inline-block;width:7px;height:7px;border-radius:4px;background:#2760FF;vertical-align:middle;margin-right:5px;margin-bottom:5px;></span>${item[2]}</span>`:`<span style=color:#FF0C0C><span style=display:inline-block;width:7px;height:7px;border-radius:4px;background:#FF0C0C;vertical-align:middle;margin-right:5px;margin-bottom:5px;></span>${item[2]}</span>`
|
||||
);
|
||||
arr.push(arrInner);
|
||||
});
|
||||
config.data = arr;
|
||||
return (
|
||||
<div className="left_down2">
|
||||
<TitleBox title="fan_run6" />
|
||||
{data.length !== 0 && (<div style={{ marginTop: "8px" }}>
|
||||
<ScrollBoard
|
||||
config={config}
|
||||
style={{ width: "476px", height: "155px" }}
|
||||
/>
|
||||
</div>)}
|
||||
{data.length === 0 && (
|
||||
<p
|
||||
style={{
|
||||
color: "#cccf",
|
||||
fontSize: "24px",
|
||||
userSelect: "none",
|
||||
textAlign: "center",
|
||||
paddingTop: "72px",
|
||||
}}
|
||||
>
|
||||
暂无数据
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
export default LeftDown2;
|
||||
72
src/page/HomePage/Left/LeftUp1/index.tsx
Normal file
@@ -0,0 +1,72 @@
|
||||
|
||||
import { useState, useEffect } from 'react';
|
||||
import TitleBox from "../../Component/TitleBox";
|
||||
import moment from 'moment';
|
||||
function LeftUp1() {
|
||||
// 时间计算工具函数
|
||||
const calculateRuntime = (startStr:any, endStr:any) => {
|
||||
const parseDate = (str:any) => {
|
||||
const [datePart, timePart] = str.split(' ');
|
||||
const [year, month, day] = datePart.split('-').map(Number);
|
||||
const [hours, minutes, seconds] = timePart.split(':').map(Number);
|
||||
return new Date(year, month - 1, day, hours, minutes, seconds);
|
||||
};
|
||||
const start = parseDate(startStr);
|
||||
const end = parseDate(endStr);
|
||||
const diff = end.getTime() - start.getTime();
|
||||
if (diff <= 0) return { days: 0, hours: 0 };
|
||||
const days = Math.floor(diff / (1000 * 60 * 60 * 24));
|
||||
const hours = Math.floor((diff % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
|
||||
return {
|
||||
days,
|
||||
hours
|
||||
};
|
||||
};
|
||||
// 数字显示组件
|
||||
const DigitalDisplay = ({ value }:any) => {
|
||||
return (
|
||||
<div style={{ display: 'inline-flex' }}>
|
||||
{value.split('').map((char:any, index:any) => (
|
||||
<span key={index} className="left_up1_numbg">
|
||||
{char}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
// 主显示组件
|
||||
const RuntimeDisplay = ({ start, end }:any) => {
|
||||
const [runtime, setRuntime] = useState({ days: 0, hours: 0 });
|
||||
useEffect(() => {
|
||||
const result = calculateRuntime(start, end);
|
||||
setRuntime(result);
|
||||
}, [start, end]);
|
||||
// 格式化数字为字符串
|
||||
const formatDays = runtime.days.toString().padStart(4, '0');
|
||||
const formatHours = runtime.hours.toString().padStart(2, '0');
|
||||
return (
|
||||
<div style={{ position: 'absolute', left: '55px', top: '64px' }}>
|
||||
<DigitalDisplay value={formatDays} />
|
||||
<span className="left_up1_text" style={{ marginLeft: 4 }}>天</span>
|
||||
<DigitalDisplay value={formatHours} />
|
||||
<span className="left_up1_text" style={{ marginLeft: 4 }}>时</span>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
const startDate = '2025-4-18 11:18:00'
|
||||
const [endDate, setEndDate] = useState(moment().format('YYYY-MM-DD HH:mm:ss'))
|
||||
useEffect(() => {
|
||||
const timer = setInterval(() => {
|
||||
setEndDate(moment().format(moment().format('YYYY-MM-DD HH:mm:ss')));
|
||||
}, 1000);
|
||||
return () => clearInterval(timer);
|
||||
}, []);
|
||||
return (
|
||||
<div className="left_up1">
|
||||
<TitleBox title="running_time6" />
|
||||
<RuntimeDisplay start={startDate} end={endDate} />
|
||||
<div className="left_up1_tip">窑炉运行时间<span style={{display: 'inline-block',lineHeight: '27px',verticalAlign: 'top',margin: '0 5px'}}>.</span>六线</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
export default LeftUp1;
|
||||
39
src/page/HomePage/Left/LeftUp2/index.tsx
Normal file
@@ -0,0 +1,39 @@
|
||||
import TitleBox from "../../Component/TitleBox";
|
||||
import img1 from "../../../../assets/image/press_img.png"
|
||||
import { useAppSelector } from "../../../../store/hooks";
|
||||
import { selectOther } from "../../../../store/HomePageSlice";
|
||||
function LeftUp2() {
|
||||
const data = useAppSelector(selectOther).窑炉压力 || '';
|
||||
// 数字显示组件
|
||||
const DigitalDisplay = ({ value }:any) => {
|
||||
return (
|
||||
value.split('').map((char:any, index:any) => (
|
||||
char !== '.'? (
|
||||
<span key={index} className="left_down1_numbg">
|
||||
{char}
|
||||
</span>
|
||||
):(<span key={index} className="left_down1_dotted"></span>)
|
||||
))
|
||||
);
|
||||
};
|
||||
return (
|
||||
<div className="left_up1">
|
||||
<TitleBox title="pressure6" />
|
||||
<div style={{position:'absolute',left:'26px',top:'64px'}}>
|
||||
{
|
||||
data === ''? (
|
||||
<>
|
||||
<span className="left_down1_numbg">-</span>
|
||||
<span className="left_down1_numbg">-</span>
|
||||
<span className="left_down1_numbg">-</span>
|
||||
</>
|
||||
):<DigitalDisplay value={data}/>
|
||||
}
|
||||
<span style={{fontSize:'30px',color:'#fff'}}>Kpa</span>
|
||||
</div>
|
||||
<div className="left_up2_tip">窑炉压力值</div>
|
||||
<img src={img1} alt="" style={{position:'absolute',width:'230px',right:'15px',top:'50px'}}/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
export default LeftUp2;
|
||||
15
src/page/HomePage/Left/index.tsx
Normal file
@@ -0,0 +1,15 @@
|
||||
import LeftUp1 from "./LeftUp1";
|
||||
import LeftUp2 from "./LeftUp2";
|
||||
import LeftDown1 from "./LeftDown1";
|
||||
import LeftDown2 from "./LeftDown2";
|
||||
function Left() {
|
||||
return (
|
||||
<div className="left_part">
|
||||
<LeftUp1 />
|
||||
<LeftUp2 />
|
||||
<LeftDown1/>
|
||||
<LeftDown2/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
export default Left;
|
||||
22
src/page/HomePage/Right/RightDown1/index.tsx
Normal file
@@ -0,0 +1,22 @@
|
||||
import TitleBox from "../../Component/TitleBox";
|
||||
import img1 from "../../../../assets/image/waterTempUp.png"
|
||||
// import img2 from "../../../../assets/image/waterTempDown.png"
|
||||
// import { useAppSelector } from "../../../../store/hooks";
|
||||
// import { selectOrderCompletionWO } from "../../../../store/HomePageSlice";
|
||||
function RightDown1() {
|
||||
// const data = useAppSelector(selectOrderCompletionWO);
|
||||
return (
|
||||
<div className="left_down1">
|
||||
<TitleBox title="water_temp5" />
|
||||
<div style={{position:'absolute',left:'45px',bottom:'100px'}}>
|
||||
<span className="left_down1_numbg">-</span>
|
||||
<span className="left_down1_numbg">-</span>
|
||||
<span className="left_down1_numbg">-</span>
|
||||
<span style={{fontSize:'30px',color:'#fff'}}>℃</span>
|
||||
</div>
|
||||
<div className="left_down1_tip" style={{bottom:'36px'}}>出口实时水温</div>
|
||||
<img src={img1} alt="" style={{position:'absolute',width:'139px',right:'68px',bottom:'36px'}}/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
export default RightDown1;
|
||||
86
src/page/HomePage/Right/RightDown2/index.tsx
Normal file
@@ -0,0 +1,86 @@
|
||||
import TitleBox from "../../Component/TitleBox";
|
||||
import ScrollBoard from "../../../Component/ScrollBoard";
|
||||
// import { useAppSelector } from "../../../../store/hooks";
|
||||
// import { selectOrderCompletionWO } from "../../../../store/HomePageSlice";
|
||||
function RightDown2() {
|
||||
// const data = useAppSelector(selectOrderCompletionWO);
|
||||
// console.log("222222封装工单完成情况+", data);
|
||||
const config = {
|
||||
header: ["序号", "设备名称", "运行频率", "设备状态"],
|
||||
headerHeight: 30,
|
||||
rowNum: 5,
|
||||
headerBGC: "rgba(4, 74, 132, 0.2)",
|
||||
oddRowBGC: "rgba(4, 74, 132, 0.2)",
|
||||
evenRowBGC: "rgba(11, 84, 153, 0.36)",
|
||||
columnWidth: [110, 180, 120, 120],
|
||||
align: ["center", "left", "left", "center"],
|
||||
data: [
|
||||
['1','产线1的名称','<span style=color:#fff>未运行</span>','<span style=color:#3984FF><span style=display:inline-block;width:7px;height:7px;border-radius:4px;background:#2760FF;vertical-align:middle;margin-right:5px;margin-bottom:5px;></span>正常</span>'],
|
||||
['2','产线1的名称','<span style=color:#30E89A>未运行</span>','<span style=color:#FF0C0C><span style=display:inline-block;width:7px;height:7px;border-radius:4px;background:#FF0C0C;vertical-align:middle;margin-right:5px;margin-bottom:5px;></span>故障</span>'],
|
||||
['3','产线1的名称','<span style=color:#fff>未运行</span>','<span style=color:#3984FF><span style=display:inline-block;width:7px;height:7px;border-radius:4px;background:#2760FF;vertical-align:middle;margin-right:5px;margin-bottom:5px;></span>正常</span>'],
|
||||
['4','产线1的名称','<span style=color:#30E89A>未运行</span>','<span style=color:#3984FF><span style=display:inline-block;width:7px;height:7px;border-radius:4px;background:#2760FF;vertical-align:middle;margin-right:5px;margin-bottom:5px;></span>正常</span>'],
|
||||
['5','产线1的名称','<span style=color:#fff>未运行</span>','<span style=color:#FF0C0C><span style=display:inline-block;width:7px;height:7px;border-radius:4px;background:#FF0C0C;vertical-align:middle;margin-right:5px;margin-bottom:5px;></span>故障</span>']
|
||||
],
|
||||
};
|
||||
// let arr: any = [];
|
||||
// data &&
|
||||
// data.map((item: any, index: any) => {
|
||||
// let arrInner = [];
|
||||
// arrInner.push(
|
||||
// item.workOrderNo ? item.workOrderNo : "-",
|
||||
// item.planQuantity
|
||||
// ? item.planQuantity
|
||||
// : item.planQuantity === 0
|
||||
// ? item.planQuantity
|
||||
// : "-",
|
||||
// item.actualPutIn
|
||||
// ? item.actualPutIn
|
||||
// : item.actualPutIn === 0
|
||||
// ? item.actualPutIn
|
||||
// : "-",
|
||||
// item.actualQuantity
|
||||
// ? item.actualQuantity
|
||||
// : item.actualQuantity === 0
|
||||
// ? item.actualQuantity
|
||||
// : "-",
|
||||
// item.completeness
|
||||
// ? item.completeness + "%"
|
||||
// : item.completeness === 0
|
||||
// ? item.completeness + "%"
|
||||
// : "-"
|
||||
// );
|
||||
// arr.push(arrInner);
|
||||
// });
|
||||
// config.data = arr;
|
||||
return (
|
||||
<div className="left_down2">
|
||||
<TitleBox title="fan_run5" />
|
||||
{/* <div style={{ marginTop: "8px" }}>
|
||||
<ScrollBoard
|
||||
config={config}
|
||||
style={{ width: "476px", height: "155px" }}
|
||||
/>
|
||||
</div> */}
|
||||
{/* {data.length !== 0 && (
|
||||
<div style={{ marginTop: "15px" }}>
|
||||
<ScrollBoard
|
||||
config={config}
|
||||
style={{ width: "500px", height: "440px" }}
|
||||
/>
|
||||
</div>
|
||||
)} */}
|
||||
<p
|
||||
style={{
|
||||
color: "#cccf",
|
||||
fontSize: "24px",
|
||||
userSelect: "none",
|
||||
textAlign: "center",
|
||||
paddingTop: "72px",
|
||||
}}
|
||||
>
|
||||
暂无数据
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
export default RightDown2;
|
||||
23
src/page/HomePage/Right/RightUp1/index.tsx
Normal file
@@ -0,0 +1,23 @@
|
||||
import TitleBox from "../../Component/TitleBox";
|
||||
// import { useAppSelector } from "../../../../store/hooks";
|
||||
// import { selectEqRateAVA } from "../../../../store/HomePageSlice";
|
||||
function RightUp1() {
|
||||
// const data = useAppSelector(selectEqRateAVA);
|
||||
return (
|
||||
<div className="left_up1">
|
||||
<TitleBox title="running_time5" />
|
||||
<div style={{position:'absolute',left:'55px',top:'64px'}}>
|
||||
<span className="left_up1_numbg">-</span>
|
||||
<span className="left_up1_numbg">-</span>
|
||||
<span className="left_up1_numbg">-</span>
|
||||
<span className="left_up1_numbg">-</span>
|
||||
<span className="left_up1_text">天</span>
|
||||
<span className="left_up1_numbg">-</span>
|
||||
<span className="left_up1_numbg">-</span>
|
||||
<span className="left_up1_text">时</span>
|
||||
</div>
|
||||
<div className="left_up1_tip">窑炉运行时间<span style={{display: 'inline-block',lineHeight: '27px',verticalAlign: 'top',margin: '0 5px'}}>.</span>五线</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
export default RightUp1;
|
||||
21
src/page/HomePage/Right/RightUp2/index.tsx
Normal file
@@ -0,0 +1,21 @@
|
||||
import TitleBox from "../../Component/TitleBox";
|
||||
import img1 from "../../../../assets/image/press_img.png"
|
||||
// import { useAppSelector } from "../../../../store/hooks";
|
||||
// import { selectEqRateAVA } from "../../../../store/HomePageSlice";
|
||||
function RightUp2() {
|
||||
// const data = useAppSelector(selectEqRateAVA);
|
||||
return (
|
||||
<div className="left_up1">
|
||||
<TitleBox title="pressure5" />
|
||||
<div style={{position:'absolute',left:'26px',top:'64px'}}>
|
||||
<span className="left_down1_numbg">-</span>
|
||||
<span className="left_down1_numbg">-</span>
|
||||
<span className="left_down1_numbg">-</span>
|
||||
<span style={{fontSize:'30px',color:'#fff'}}>Kpa</span>
|
||||
</div>
|
||||
<div className="left_up2_tip">窑炉压力值</div>
|
||||
<img src={img1} alt="" style={{position:'absolute',width:'230px',right:'15px',top:'50px'}}/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
export default RightUp2;
|
||||
15
src/page/HomePage/Right/index.tsx
Normal file
@@ -0,0 +1,15 @@
|
||||
import RightDown2 from "./RightDown2";
|
||||
import RightUp1 from "./RightUp1";
|
||||
import RightUp2 from "./RightUp2";
|
||||
import RightDown1 from "./RightDown1"
|
||||
function Right() {
|
||||
return (
|
||||
<div className="right_part">
|
||||
<RightUp1 />
|
||||
<RightUp2 />
|
||||
<RightDown1 />
|
||||
<RightDown2 />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
export default Right;
|
||||
346
src/page/HomePage/index.css
Normal file
@@ -0,0 +1,346 @@
|
||||
@font-face {
|
||||
font-family: "站酷庆科黄油体";
|
||||
src: url("../../assets/fonts/站酷庆科黄油体.ttf");
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
.left_part {
|
||||
width: 542px;
|
||||
position: absolute;
|
||||
top: 82px;
|
||||
margin-left: 52px;
|
||||
}
|
||||
.left_up1 {
|
||||
width: 523px;
|
||||
height: 224px;
|
||||
box-sizing: border-box;
|
||||
background: url(../../../public/image/homePage/L1.png) no-repeat;
|
||||
background-size: 100% 100%;
|
||||
background-position: 0 0;
|
||||
margin-bottom: 24px;
|
||||
padding: 12px 0 0 20px;
|
||||
position: relative;
|
||||
backdrop-filter: blur(2px);
|
||||
}
|
||||
.left_up1_numbg{
|
||||
display: inline-block;
|
||||
width: 46px;
|
||||
height: 62px;
|
||||
background: url(../../../public/image/homePage/num_box2.png) no-repeat;
|
||||
background-size: 100% 100%;
|
||||
background-position: 0 0;
|
||||
margin-right: 5px;
|
||||
font-family: "站酷庆科黄油体";
|
||||
font-size: 58px;
|
||||
color: #FFFFFF;
|
||||
text-align: center;
|
||||
line-height: 60px;
|
||||
vertical-align: bottom;
|
||||
}
|
||||
.left_up1_text{
|
||||
display: inline-block;
|
||||
width: 46px;
|
||||
height: 53px;
|
||||
background: url(../../../public/image/homePage/num_box3.png) no-repeat;
|
||||
background-size: 100% 100%;
|
||||
background-position: 0 0;
|
||||
margin-right: 5px;
|
||||
font-family: "站酷庆科黄油体";
|
||||
font-size: 36px;
|
||||
color: #FFFFFF;
|
||||
text-align: center;
|
||||
line-height: 55px;
|
||||
vertical-align: bottom;
|
||||
}
|
||||
.left_up1_tip {
|
||||
position: absolute;
|
||||
left: 110px;
|
||||
bottom: 30px;
|
||||
font-size: 33px;
|
||||
color: #FFFFFF;
|
||||
letter-spacing: 3px;
|
||||
}
|
||||
.left_up1_tip::after {
|
||||
content: "";
|
||||
display: inline-block;
|
||||
width: 430px;
|
||||
height: 4px;
|
||||
background: linear-gradient( 270deg, rgba(138,231,248,0) 0%, #6FE2FF 51%, rgba(82,203,239,0) 100%);
|
||||
filter: blur(1px);
|
||||
position: absolute;
|
||||
top: 39px;
|
||||
left: -60px;
|
||||
}
|
||||
.left_up2_tip {
|
||||
position: absolute;
|
||||
left: 50px;
|
||||
bottom: 42px;
|
||||
font-size: 33px;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
.left_up2_tip::after {
|
||||
content: "";
|
||||
display: inline-block;
|
||||
width: 210px;
|
||||
height: 4px;
|
||||
background: linear-gradient( 270deg, rgba(138,231,248,0) 0%, #6FE2FF 51%, rgba(82,203,239,0) 100%);
|
||||
filter: blur(1px);
|
||||
position: absolute;
|
||||
top: 39px;
|
||||
left: -19px;
|
||||
}
|
||||
.left_down1 {
|
||||
width: 523px;
|
||||
height: 224px;
|
||||
box-sizing: border-box;
|
||||
background: url(../../../public/image/homePage/L2.png) no-repeat;
|
||||
background-size: 100% 100%;
|
||||
background-position: 0 0;
|
||||
margin-bottom: 24px;
|
||||
padding: 12px 0 0 20px;
|
||||
position: relative;
|
||||
backdrop-filter: blur(2px);
|
||||
}
|
||||
.left_down1_tip {
|
||||
position: absolute;
|
||||
left: 66px;
|
||||
font-size: 33px;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
.left_down1_numbg{
|
||||
display: inline-block;
|
||||
width: 45px;
|
||||
height: 55px;
|
||||
background: url(../../../public/image/homePage/num_box1.png) no-repeat;
|
||||
background-size: 100% 100%;
|
||||
background-position: 0 0;
|
||||
margin-right: 5px;
|
||||
font-family: "站酷庆科黄油体";
|
||||
font-size: 58px;
|
||||
color: #FFFFFF;
|
||||
text-align: center;
|
||||
line-height: 55px;
|
||||
vertical-align: bottom;
|
||||
}
|
||||
.left_down1_dotted{
|
||||
display: inline-block;
|
||||
width: 7px;
|
||||
height: 9px;
|
||||
background: url(../../../public/image/homePage/dotted.png) no-repeat;
|
||||
background-size: 100% 100%;
|
||||
background-position: 0 0;
|
||||
margin-right: 5px;
|
||||
vertical-align: bottom;
|
||||
}
|
||||
.left_down1_tip::after {
|
||||
content: "";
|
||||
display: inline-block;
|
||||
width: 236px;
|
||||
height: 4px;
|
||||
background: linear-gradient( 270deg, rgba(138,231,248,0) 0%, #6FE2FF 51%, rgba(82,203,239,0) 100%);
|
||||
filter: blur(1px);
|
||||
position: absolute;
|
||||
top: 39px;
|
||||
left: -19px;
|
||||
}
|
||||
.left_down2 {
|
||||
width: 523px;
|
||||
height: 232px;
|
||||
box-sizing: border-box;
|
||||
background: url(../../../public/image/homePage/L2.png) no-repeat;
|
||||
background-size: 100% 100%;
|
||||
background-position: 0 0;
|
||||
padding: 12px 0 0 20px;
|
||||
backdrop-filter: blur(2px);
|
||||
}
|
||||
/* 中间部分 */
|
||||
.center_up_box {
|
||||
width: 4557px;
|
||||
height: 624px;
|
||||
position: absolute;
|
||||
top: 180px;
|
||||
left: 602px;
|
||||
}
|
||||
.center_up_top1 {
|
||||
width: 466px;
|
||||
height: 152px;
|
||||
box-sizing: border-box;
|
||||
background: url(../../../public/image/homePage/center_top.png) no-repeat;
|
||||
background-size: 100% 100%;
|
||||
position: absolute;
|
||||
left: 1455px;
|
||||
backdrop-filter: blur(2px);
|
||||
}
|
||||
.center_up_top2 {
|
||||
width: 574px;
|
||||
height: 152px;
|
||||
box-sizing: border-box;
|
||||
background: url(../../../public/image/homePage/center_top.png) no-repeat;
|
||||
background-size: 100% 100%;
|
||||
position: absolute;
|
||||
left: 1940px;
|
||||
backdrop-filter: blur(2px);
|
||||
}
|
||||
.center_up_top1_text {
|
||||
width: 355px;
|
||||
height: 152px;
|
||||
padding-top:22px;
|
||||
padding-left: 10px;
|
||||
box-sizing: border-box;
|
||||
position: absolute;
|
||||
right:0;
|
||||
}
|
||||
.center_up_top1_text div {
|
||||
display: inline-block;
|
||||
color:#fff;
|
||||
padding:0 15px;
|
||||
}
|
||||
.center_up_top_text_split {
|
||||
display: inline-block;
|
||||
width: 1px;
|
||||
height: 85px;
|
||||
background: linear-gradient(
|
||||
to bottom,
|
||||
rgba(167, 169, 171, 1) 0%,
|
||||
rgba(237, 237, 237, 1) 50%,
|
||||
rgba(255, 255, 255, 1) 100%
|
||||
);
|
||||
}
|
||||
.center_up_top2_text {
|
||||
width: 463px;
|
||||
height: 152px;
|
||||
padding-top:22px;
|
||||
padding-left: 10px;
|
||||
box-sizing: border-box;
|
||||
position: absolute;
|
||||
right:0;
|
||||
}
|
||||
.center_up_top2_text div {
|
||||
display: inline-block;
|
||||
color:#fff;
|
||||
padding:0 15px;
|
||||
}
|
||||
.line_up {
|
||||
width: 4400px;
|
||||
height: 280px;
|
||||
box-sizing: border-box;
|
||||
background: url(../../../public/image/homePage/line1.png) no-repeat;
|
||||
background-size: 100% 100%;
|
||||
position: absolute;
|
||||
left: 80px;
|
||||
top:100px
|
||||
}
|
||||
.line_down {
|
||||
width: 4400px;
|
||||
height: 280px;
|
||||
box-sizing: border-box;
|
||||
background: url(../../../public/image/homePage/line2.png) no-repeat;
|
||||
background-size: 100% 100%;
|
||||
position: absolute;
|
||||
left: 80px;
|
||||
bottom:-20px
|
||||
}
|
||||
.center_up .eqbg1 {
|
||||
width: 175px;
|
||||
height: 81px;
|
||||
position:absolute;
|
||||
background: url(../../../public/image/homePage/eq_bg1.png) no-repeat;
|
||||
background-size: 100% 100%;
|
||||
padding: 8px 0 0 25px;
|
||||
box-sizing: border-box;
|
||||
backdrop-filter: blur(4px);
|
||||
}
|
||||
.center_up .eqbg_text{
|
||||
font-weight: 500;
|
||||
font-size: 19px;
|
||||
color: #FFFFFF;
|
||||
letter-spacing: 5px;
|
||||
z-index: 2;
|
||||
}
|
||||
.center_up .eqbg_num{
|
||||
font-weight: 500;
|
||||
font-size: 41px;
|
||||
color: #00F4FF;
|
||||
line-height: 34px;
|
||||
z-index: 2;
|
||||
}
|
||||
.center_up .eqbg2 {
|
||||
width: 175px;
|
||||
height: 81px;
|
||||
position:absolute;
|
||||
background: url(../../../public/image/homePage/eq_bg2.png) no-repeat;
|
||||
background-size: 100% 100%;
|
||||
padding: 8px 0 0 25px;
|
||||
box-sizing: border-box;
|
||||
backdrop-filter: blur(4px);
|
||||
}
|
||||
.center_down_box {
|
||||
width: 4600px;
|
||||
height: 230px;
|
||||
position: absolute;
|
||||
bottom: 23px;
|
||||
left: 602px;
|
||||
}
|
||||
.center_down {
|
||||
width: 440px;
|
||||
height: 230px;
|
||||
box-sizing: border-box;
|
||||
background: url(../../../public/image/homePage/L2.png) no-repeat;
|
||||
background-size: 100% 100%;
|
||||
background-position: 0 0;
|
||||
padding: 12px 15px 15px;
|
||||
position:relative;
|
||||
margin-right: 18px;
|
||||
backdrop-filter: blur(2px);
|
||||
}
|
||||
.chart_blur_bg {
|
||||
height: 174px;
|
||||
padding: 5px 10px 0px 5px;
|
||||
box-sizing: border-box;
|
||||
background: url(../../../public/image/homePage/cd1.png) no-repeat;
|
||||
background-size: 100% 100%;
|
||||
background-position: 0 0;
|
||||
border-radius: 10px;
|
||||
}
|
||||
.legend_right {
|
||||
position: absolute;
|
||||
right: 17px;
|
||||
top: 25px;
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
font-size: 14px;
|
||||
}
|
||||
.legend_right .dot {
|
||||
display: inline-block;
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
margin-right: 5px;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.right_part {
|
||||
width: 524px;
|
||||
position: absolute;
|
||||
top: 82px;
|
||||
right: 43px;
|
||||
}
|
||||
|
||||
.dv-scroll-board {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
.dv-scroll-board .header .header-item,
|
||||
.dv-scroll-board .rows .ceil {
|
||||
border-right: 1px solid #0b193e;
|
||||
}
|
||||
.dv-scroll-board .header .header-item:last-child,
|
||||
.dv-scroll-board .rows .ceil:last-child {
|
||||
border-right: none;
|
||||
border: none;
|
||||
}
|
||||
.dv-scroll-board .header {
|
||||
font-size: 18px;
|
||||
}
|
||||
.dv-scroll-board .rows .row-item {
|
||||
font-size: 16px;
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
}
|
||||
19
src/page/HomePage/index.tsx
Normal file
@@ -0,0 +1,19 @@
|
||||
import React from "react";
|
||||
import TopTitle from "../Component/TopTitle";
|
||||
import Left from "./Left";
|
||||
import Center from "./Center/Center";
|
||||
import Right from "./Right";
|
||||
import "./index.css";
|
||||
function HomePage() {
|
||||
return (
|
||||
<React.Fragment>
|
||||
<TopTitle />
|
||||
<div>
|
||||
<Left />
|
||||
<Center />
|
||||
<Right />
|
||||
</div>
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
export default HomePage;
|
||||
71
src/react-app-env.d.ts
vendored
Normal file
@@ -0,0 +1,71 @@
|
||||
/// <reference types="node" />
|
||||
/// <reference types="react" />
|
||||
/// <reference types="react-dom" />
|
||||
|
||||
declare namespace NodeJS {
|
||||
interface ProcessEnv {
|
||||
readonly NODE_ENV: 'development' | 'production' | 'test';
|
||||
readonly PUBLIC_URL: string;
|
||||
}
|
||||
}
|
||||
|
||||
declare module '*.avif' {
|
||||
const src: string;
|
||||
export default src;
|
||||
}
|
||||
|
||||
declare module '*.bmp' {
|
||||
const src: string;
|
||||
export default src;
|
||||
}
|
||||
|
||||
declare module '*.gif' {
|
||||
const src: string;
|
||||
export default src;
|
||||
}
|
||||
|
||||
declare module '*.jpg' {
|
||||
const src: string;
|
||||
export default src;
|
||||
}
|
||||
|
||||
declare module '*.jpeg' {
|
||||
const src: string;
|
||||
export default src;
|
||||
}
|
||||
|
||||
declare module '*.png' {
|
||||
const src: string;
|
||||
export default src;
|
||||
}
|
||||
|
||||
declare module '*.webp' {
|
||||
const src: string;
|
||||
export default src;
|
||||
}
|
||||
|
||||
declare module '*.svg' {
|
||||
import * as React from 'react';
|
||||
|
||||
export const ReactComponent: React.FunctionComponent<React.SVGProps<
|
||||
SVGSVGElement
|
||||
> & { title?: string }>;
|
||||
|
||||
const src: string;
|
||||
export default src;
|
||||
}
|
||||
|
||||
declare module '*.module.css' {
|
||||
const classes: { readonly [key: string]: string };
|
||||
export default classes;
|
||||
}
|
||||
|
||||
declare module '*.module.scss' {
|
||||
const classes: { readonly [key: string]: string };
|
||||
export default classes;
|
||||
}
|
||||
|
||||
declare module '*.module.sass' {
|
||||
const classes: { readonly [key: string]: string };
|
||||
export default classes;
|
||||
}
|
||||
15
src/reportWebVitals.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import { ReportHandler } from 'web-vitals';
|
||||
|
||||
const reportWebVitals = (onPerfEntry?: ReportHandler) => {
|
||||
if (onPerfEntry && onPerfEntry instanceof Function) {
|
||||
import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
|
||||
getCLS(onPerfEntry);
|
||||
getFID(onPerfEntry);
|
||||
getFCP(onPerfEntry);
|
||||
getLCP(onPerfEntry);
|
||||
getTTFB(onPerfEntry);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
export default reportWebVitals;
|
||||
5
src/setupTests.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
// jest-dom adds custom jest matchers for asserting on DOM nodes.
|
||||
// allows you to do things like:
|
||||
// expect(element).toHaveTextContent(/react/i)
|
||||
// learn more: https://github.com/testing-library/jest-dom
|
||||
import '@testing-library/jest-dom';
|
||||
41
src/store/HomePageSlice.ts
Normal file
@@ -0,0 +1,41 @@
|
||||
import { createSlice } from "@reduxjs/toolkit";
|
||||
import type { RootState } from "./store";
|
||||
export interface HomePageSliceInterface {
|
||||
lineChart: any;
|
||||
fan:any;
|
||||
otherMsg:any;
|
||||
}
|
||||
const initialState: HomePageSliceInterface = {
|
||||
lineChart: {},
|
||||
fan:[],
|
||||
otherMsg:{}
|
||||
};
|
||||
export const HomePageSlice = createSlice({
|
||||
name: "HomePageSlice",
|
||||
initialState,
|
||||
reducers: {
|
||||
UpdateLineChart: (state, action) => {
|
||||
state.lineChart = action.payload;
|
||||
},
|
||||
UpdateFan: (state, action) => {
|
||||
state.fan = action.payload;
|
||||
},
|
||||
UpdateOther: (state, action) => {
|
||||
state.otherMsg = action.payload;
|
||||
}
|
||||
},
|
||||
});
|
||||
export const {
|
||||
UpdateLineChart,
|
||||
UpdateFan,
|
||||
UpdateOther
|
||||
} = HomePageSlice.actions;
|
||||
|
||||
export const selectLineChart = (state: RootState) =>
|
||||
state.HomePageSlice.lineChart;
|
||||
export const selectFan = (state: RootState) =>
|
||||
state.HomePageSlice.fan;
|
||||
export const selectOther = (state: RootState) =>
|
||||
state.HomePageSlice.otherMsg;
|
||||
|
||||
export default HomePageSlice.reducer;
|
||||
68
src/store/UpdateData.tsx
Normal file
@@ -0,0 +1,68 @@
|
||||
// import { useState } from "react";
|
||||
// import axios from "axios";
|
||||
import {
|
||||
UpdateLineChart,
|
||||
UpdateFan,
|
||||
UpdateOther
|
||||
} from "./HomePageSlice";
|
||||
import { useAppDispatch } from "./hooks";
|
||||
|
||||
function UpdateData() {
|
||||
// const [myUrl, setUrl] = useState("");
|
||||
// axios.get("/wsconfig.json").then((r) => {
|
||||
// setUrl(r.data.url);
|
||||
// });
|
||||
// const myUrl = window.location.host;
|
||||
const myUrl = "192.168.82.45:8081";
|
||||
let websocketHome = null;
|
||||
if ("WebSocket" in window) {
|
||||
websocketHome = new WebSocket(
|
||||
"ws://" + myUrl + "/dj-screen/websocket/1"
|
||||
);
|
||||
//连接成功建立的回调方法
|
||||
} else {
|
||||
alert("Not support websocket");
|
||||
}
|
||||
// @ts-ignore
|
||||
websocketHome.onopen = function (event) {
|
||||
console.log("websocketHome-open");
|
||||
};
|
||||
interface MsgDataType {
|
||||
type: string;
|
||||
}
|
||||
// const [msgData, setMsgData] = useState<MsgDataType | null>(null);
|
||||
//接收到消息的回调方法
|
||||
// @ts-ignore
|
||||
websocketHome.onmessage = function (event) {
|
||||
// console.log("接收到消息:", event);
|
||||
let msgData: MsgDataType = { type: "example" };
|
||||
try {
|
||||
msgData = JSON.parse(event.data);
|
||||
} catch (error) {
|
||||
console.log("websocket: [unable to msgData] : ", event.data);
|
||||
}
|
||||
if (!msgData) return;
|
||||
switch (msgData?.type) {
|
||||
case "one": {
|
||||
// @ts-ignore
|
||||
dispatch(UpdateLineChart(msgData.data));
|
||||
break;
|
||||
}
|
||||
case "two": {
|
||||
// @ts-ignore
|
||||
dispatch(UpdateFan(msgData.data));
|
||||
break;
|
||||
}
|
||||
case "three": {
|
||||
// @ts-ignore
|
||||
dispatch(UpdateOther(msgData.data));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
}
|
||||
};
|
||||
const dispatch = useAppDispatch();
|
||||
return null;
|
||||
}
|
||||
|
||||
export default UpdateData;
|
||||
6
src/store/hooks.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
import { TypedUseSelectorHook, useDispatch, useSelector } from 'react-redux';
|
||||
import type { RootState, AppDispatch } from './store';
|
||||
|
||||
// Use throughout your app instead of plain `useDispatch` and `useSelector`
|
||||
export const useAppDispatch = () => useDispatch<AppDispatch>();
|
||||
export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector;
|
||||
11
src/store/store.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import { configureStore } from "@reduxjs/toolkit";
|
||||
import HomePageReducer from "./HomePageSlice";
|
||||
|
||||
export const store = configureStore({
|
||||
reducer: {
|
||||
HomePageSlice: HomePageReducer,
|
||||
},
|
||||
});
|
||||
|
||||
export type AppDispatch = typeof store.dispatch;
|
||||
export type RootState = ReturnType<typeof store.getState>;
|
||||
12
src/utils/index.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
export function generateTimeLabels (length:any) {
|
||||
const totalHours = 23; // 0:00 到 23:00
|
||||
const interval = totalHours / (length - 1); // 小时间隔
|
||||
return Array.from({ length }, (_, index) => {
|
||||
const decimalHours = interval * index;
|
||||
const hours = Math.floor(decimalHours);
|
||||
const minutes = Math.round((decimalHours % 1) * 60);
|
||||
const safeHours = Math.min(hours, 23);
|
||||
const safeMinutes = Math.min(minutes, 59);
|
||||
return `${String(safeHours).padStart(2, '0')}:${String(safeMinutes).padStart(2, '0')}`;
|
||||
});
|
||||
};
|
||||