大屏样式
This commit is contained in:
		
							
								
								
									
										11
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										11
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							@@ -36,6 +36,7 @@
 | 
			
		||||
        "browserslist": "^4.18.1",
 | 
			
		||||
        "camelcase": "^6.2.1",
 | 
			
		||||
        "case-sensitive-paths-webpack-plugin": "^2.4.0",
 | 
			
		||||
        "classnames": "^2.5.1",
 | 
			
		||||
        "css-loader": "^6.5.1",
 | 
			
		||||
        "css-minimizer-webpack-plugin": "^3.2.0",
 | 
			
		||||
        "dotenv": "^10.0.0",
 | 
			
		||||
@@ -5939,6 +5940,11 @@
 | 
			
		||||
      "resolved": "https://registry.npmmirror.com/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz",
 | 
			
		||||
      "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA=="
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/classnames": {
 | 
			
		||||
      "version": "2.5.1",
 | 
			
		||||
      "resolved": "https://registry.npmmirror.com/classnames/-/classnames-2.5.1.tgz",
 | 
			
		||||
      "integrity": "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow=="
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/clean-css": {
 | 
			
		||||
      "version": "5.3.2",
 | 
			
		||||
      "resolved": "https://registry.npmmirror.com/clean-css/-/clean-css-5.3.2.tgz",
 | 
			
		||||
@@ -21198,6 +21204,11 @@
 | 
			
		||||
      "resolved": "https://registry.npmmirror.com/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz",
 | 
			
		||||
      "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA=="
 | 
			
		||||
    },
 | 
			
		||||
    "classnames": {
 | 
			
		||||
      "version": "2.5.1",
 | 
			
		||||
      "resolved": "https://registry.npmmirror.com/classnames/-/classnames-2.5.1.tgz",
 | 
			
		||||
      "integrity": "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow=="
 | 
			
		||||
    },
 | 
			
		||||
    "clean-css": {
 | 
			
		||||
      "version": "5.3.2",
 | 
			
		||||
      "resolved": "https://registry.npmmirror.com/clean-css/-/clean-css-5.3.2.tgz",
 | 
			
		||||
 
 | 
			
		||||
@@ -31,6 +31,7 @@
 | 
			
		||||
    "browserslist": "^4.18.1",
 | 
			
		||||
    "camelcase": "^6.2.1",
 | 
			
		||||
    "case-sensitive-paths-webpack-plugin": "^2.4.0",
 | 
			
		||||
    "classnames": "^2.5.1",
 | 
			
		||||
    "css-loader": "^6.5.1",
 | 
			
		||||
    "css-minimizer-webpack-plugin": "^3.2.0",
 | 
			
		||||
    "dotenv": "^10.0.0",
 | 
			
		||||
 
 | 
			
		||||
@@ -11,41 +11,11 @@ import {
 | 
			
		||||
  Observable,
 | 
			
		||||
  Vector3,
 | 
			
		||||
} from "@babylonjs/core";
 | 
			
		||||
import {
 | 
			
		||||
  GlassAnimation1_1,
 | 
			
		||||
  GlassAnimation1_2D,
 | 
			
		||||
  GlassAnimation1_2U,
 | 
			
		||||
  GlassAnimation1_3,
 | 
			
		||||
  GlassAnimation1_4,
 | 
			
		||||
  GlassAnimation2_1,
 | 
			
		||||
  GlassAnimation2_2D,
 | 
			
		||||
  GlassAnimation2_2U,
 | 
			
		||||
  GlassAnimation2_3,
 | 
			
		||||
  GlassAnimation2_4,
 | 
			
		||||
  GlassAnimation3_1,
 | 
			
		||||
  GlassAnimation3_2D,
 | 
			
		||||
  GlassAnimation3_2U,
 | 
			
		||||
  GlassAnimation3_3,
 | 
			
		||||
  GlassAnimation3_4,
 | 
			
		||||
  GlassAnimation4_1,
 | 
			
		||||
  GlassAnimation4_2D,
 | 
			
		||||
  GlassAnimation4_2U,
 | 
			
		||||
  GlassAnimation4_3,
 | 
			
		||||
  GlassAnimation4_4,
 | 
			
		||||
} from "./GlassAnimation";
 | 
			
		||||
import { useAppSelector } from "../store/hooks";
 | 
			
		||||
import {
 | 
			
		||||
  GlassStatus,
 | 
			
		||||
  selectGlassStatus,
 | 
			
		||||
} from "../store/ProductionMonitoringEntity";
 | 
			
		||||
import "../page/style/standard.css";
 | 
			
		||||
import { MyObservable } from "../context/MyObservable";
 | 
			
		||||
import { Button, ButtonGroup } from "@mui/material";
 | 
			
		||||
import intl from "react-intl-universal";
 | 
			
		||||
import { EquStatusInterface, selectEquStatus } from "../store/EquStatusEntity";
 | 
			
		||||
import EquMap from "./EquMap";
 | 
			
		||||
 | 
			
		||||
const onMainCamObservable = new Observable();
 | 
			
		||||
const onEquObservable = new Observable();
 | 
			
		||||
 | 
			
		||||
const myStyle = {
 | 
			
		||||
@@ -54,57 +24,18 @@ const myStyle = {
 | 
			
		||||
  outline: "none",
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const DetailCamera = {
 | 
			
		||||
  alpha: BABYLON.Tools.ToRadians(270),
 | 
			
		||||
  beta: BABYLON.Tools.ToRadians(25),
 | 
			
		||||
  radius: 120,
 | 
			
		||||
  target: new BABYLON.Vector3(-110, 0, -8),
 | 
			
		||||
  // Part_1: {
 | 
			
		||||
  //   alpha: BABYLON.Tools.ToRadians(270),
 | 
			
		||||
  //   beta: BABYLON.Tools.ToRadians(25),
 | 
			
		||||
  //   radius: 85,
 | 
			
		||||
  //   target: new BABYLON.Vector3(-110, 0, -8),
 | 
			
		||||
  // },
 | 
			
		||||
  // Part_2: {
 | 
			
		||||
  //   alpha: BABYLON.Tools.ToRadians(270),
 | 
			
		||||
  //   beta: BABYLON.Tools.ToRadians(25),
 | 
			
		||||
  //   radius: 85,
 | 
			
		||||
  //   target: new BABYLON.Vector3(-40, 0, -8),
 | 
			
		||||
  // },
 | 
			
		||||
  // Part_3: {
 | 
			
		||||
  //   alpha: BABYLON.Tools.ToRadians(270),
 | 
			
		||||
  //   beta: BABYLON.Tools.ToRadians(25),
 | 
			
		||||
  //   radius: 85,
 | 
			
		||||
  //   target: new BABYLON.Vector3(0, 0, -8),
 | 
			
		||||
  // },
 | 
			
		||||
  // Part_4: {
 | 
			
		||||
  //   alpha: BABYLON.Tools.ToRadians(270),
 | 
			
		||||
  //   beta: BABYLON.Tools.ToRadians(25),
 | 
			
		||||
  //   radius: 85,
 | 
			
		||||
  //   target: new BABYLON.Vector3(110, 0, -8),
 | 
			
		||||
  // },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
interface MybabylonJSProps {
 | 
			
		||||
  modelPath: string; // 明确 modelPath 属性的类型为 string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function MybabylonJS({ modelPath }: MybabylonJSProps) {
 | 
			
		||||
  const onGlassObservable = useContext(MyObservable);
 | 
			
		||||
  const EquStatus = useAppSelector(selectEquStatus);
 | 
			
		||||
  const canvasRef = useRef(null);
 | 
			
		||||
  onEquObservable.notifyObservers(EquStatus);
 | 
			
		||||
  // const thisLineGlassStatus = useAppSelector(selectGlassStatus)
 | 
			
		||||
  // onGlassObservable.notifyObservers(thisLineGlassStatus)
 | 
			
		||||
  const [SelectedMeshName, setSelectedMeshName] = useState<string | null>(null);
 | 
			
		||||
 | 
			
		||||
  interface MybabylonJSProps {
 | 
			
		||||
    modelPath: string;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // 使用 useRef 来存储当前加载的模型引用
 | 
			
		||||
  const currentMeshesRef = useRef<Array<BABYLON.AbstractMesh>>([]);
 | 
			
		||||
 | 
			
		||||
  useEffect(() => {
 | 
			
		||||
    // 确保 canvas 引用存在
 | 
			
		||||
    if (!canvasRef.current) return;
 | 
			
		||||
@@ -120,19 +51,6 @@ function MybabylonJS({ modelPath }: MybabylonJSProps) {
 | 
			
		||||
      const scene = new BABYLON.Scene(engine);
 | 
			
		||||
      scene.clearColor = new BABYLON.Color4(0, 0, 0, 0);
 | 
			
		||||
 | 
			
		||||
      const light = new BABYLON.DirectionalLight(
 | 
			
		||||
        "light",
 | 
			
		||||
        new BABYLON.Vector3(20, 20, 100),
 | 
			
		||||
        scene
 | 
			
		||||
      );
 | 
			
		||||
      const light2 = new BABYLON.PointLight(
 | 
			
		||||
        "light2",
 | 
			
		||||
        new BABYLON.Vector3(20, 20, 100),
 | 
			
		||||
        scene
 | 
			
		||||
      );
 | 
			
		||||
 | 
			
		||||
      const Glass1_1 = new BABYLON.TransformNode("Glass1_1");
 | 
			
		||||
 | 
			
		||||
      const baseLight = new HemisphericLight(
 | 
			
		||||
        "hemiLight",
 | 
			
		||||
        new Vector3(-1, 1, 0),
 | 
			
		||||
@@ -148,9 +66,14 @@ function MybabylonJS({ modelPath }: MybabylonJSProps) {
 | 
			
		||||
        "camera",
 | 
			
		||||
        BABYLON.Tools.ToRadians(245),
 | 
			
		||||
        BABYLON.Tools.ToRadians(25),
 | 
			
		||||
        90,
 | 
			
		||||
        modelPath.slice(-1) === "1"
 | 
			
		||||
          ? 110
 | 
			
		||||
          : modelPath.slice(-3) === "5-2"
 | 
			
		||||
          ? 100
 | 
			
		||||
          : 80,
 | 
			
		||||
        new BABYLON.Vector3(-13, 0, 0)
 | 
			
		||||
      );
 | 
			
		||||
      console.log("camera", camera);
 | 
			
		||||
      camera.lowerRadiusLimit = 10;
 | 
			
		||||
      camera.upperRadiusLimit = 600;
 | 
			
		||||
 | 
			
		||||
@@ -194,8 +117,6 @@ function MybabylonJS({ modelPath }: MybabylonJSProps) {
 | 
			
		||||
      let hl = new BABYLON.HighlightLayer("hl1", scene);
 | 
			
		||||
      let hl2 = new BABYLON.HighlightLayer("hl2", scene);
 | 
			
		||||
 | 
			
		||||
      // var LOD0MESH = await BABYLON.SceneLoader.ImportMeshAsync('', '/test/', `${modelPath}.babylon`, scene);
 | 
			
		||||
 | 
			
		||||
      // 定义一个函数来加载或重新加载模型
 | 
			
		||||
      const loadOrReloadModel = async () => {
 | 
			
		||||
        // 在加载新模型之前卸载已加载的模型
 | 
			
		||||
@@ -213,11 +134,6 @@ function MybabylonJS({ modelPath }: MybabylonJSProps) {
 | 
			
		||||
            `${modelPath}.babylon`,
 | 
			
		||||
            scene
 | 
			
		||||
          );
 | 
			
		||||
          // var LOD0MESH = await BABYLON.SceneLoader.ImportMeshAsync('', '/test/', `line1.babylon`, scene);
 | 
			
		||||
          // var LOD1MESH = await BABYLON.SceneLoader.ImportMeshAsync('', '/test/', `line2.babylon`, scene);
 | 
			
		||||
          // var LOD2MESH = await BABYLON.SceneLoader.ImportMeshAsync('', '/test/', `line3.babylon`, scene);
 | 
			
		||||
          // var LOD3MESH = await BABYLON.SceneLoader.ImportMeshAsync('', '/test/', `line4.babylon`, scene);
 | 
			
		||||
          // var LOD4MESH = await BABYLON.SceneLoader.ImportMeshAsync('', '/test/', `line5.babylon`, scene);
 | 
			
		||||
          // 将新加载的模型添加到 currentMeshesRef 中
 | 
			
		||||
          currentMeshesRef.current.push(...LOD0MESH.meshes);
 | 
			
		||||
 | 
			
		||||
@@ -264,7 +180,6 @@ function MybabylonJS({ modelPath }: MybabylonJSProps) {
 | 
			
		||||
            };
 | 
			
		||||
          });
 | 
			
		||||
 | 
			
		||||
          /////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
          onEquObservable.add((eventData, eventState) => {
 | 
			
		||||
            LOD0MESH.meshes.find((mesh) => {
 | 
			
		||||
              // @ts-ignore
 | 
			
		||||
@@ -285,8 +200,6 @@ function MybabylonJS({ modelPath }: MybabylonJSProps) {
 | 
			
		||||
              }
 | 
			
		||||
            });
 | 
			
		||||
          });
 | 
			
		||||
 | 
			
		||||
          /////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
        } catch (error) {
 | 
			
		||||
          console.error("加载模型失败:", error);
 | 
			
		||||
        }
 | 
			
		||||
@@ -299,50 +212,22 @@ function MybabylonJS({ modelPath }: MybabylonJSProps) {
 | 
			
		||||
        camera.target = new BABYLON.Vector3(-13, 0, 0);
 | 
			
		||||
        camera.alpha = BABYLON.Tools.ToRadians(245);
 | 
			
		||||
        camera.beta = BABYLON.Tools.ToRadians(25);
 | 
			
		||||
        camera.radius = 90;
 | 
			
		||||
        camera.radius =
 | 
			
		||||
          modelPath.slice(-1) === "1"
 | 
			
		||||
            ? 110
 | 
			
		||||
            : modelPath.slice(-3) === "5-2"
 | 
			
		||||
            ? 100
 | 
			
		||||
            : 80;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      let resetCamera = setTimeout(reset, 15000);
 | 
			
		||||
      scene.onPointerObservable.add((pointerInfo) => {
 | 
			
		||||
        // console.log(camera.target, camera.alpha * 180 / 3.14, camera.beta * 180 / 3.14, camera.radius)
 | 
			
		||||
        switch (pointerInfo.type) {
 | 
			
		||||
          case BABYLON.PointerEventTypes.POINTERMOVE:
 | 
			
		||||
            clearTimeout(resetCamera);
 | 
			
		||||
            resetCamera = setTimeout(reset, 15000);
 | 
			
		||||
        }
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
      // onMainCamObservable.add((eventData, eventState) => {
 | 
			
		||||
      //   clearTimeout(resetCamera);
 | 
			
		||||
      //   resetCamera = setTimeout(reset, 5000);
 | 
			
		||||
      //   switch (eventData) {
 | 
			
		||||
      //     case 1:
 | 
			
		||||
      //       camera.target = DetailCamera.Part_1.target;
 | 
			
		||||
      //       camera.alpha = DetailCamera.Part_1.alpha;
 | 
			
		||||
      //       camera.beta = DetailCamera.Part_1.beta;
 | 
			
		||||
      //       camera.radius = DetailCamera.Part_1.radius;
 | 
			
		||||
      //       break;
 | 
			
		||||
      //     case 2:
 | 
			
		||||
      //       camera.target = DetailCamera.Part_2.target;
 | 
			
		||||
      //       camera.alpha = DetailCamera.Part_2.alpha;
 | 
			
		||||
      //       camera.beta = DetailCamera.Part_2.beta;
 | 
			
		||||
      //       camera.radius = DetailCamera.Part_2.radius;
 | 
			
		||||
      //       break;
 | 
			
		||||
      //     case 3:
 | 
			
		||||
      //       camera.target = DetailCamera.Part_3.target;
 | 
			
		||||
      //       camera.alpha = DetailCamera.Part_3.alpha;
 | 
			
		||||
      //       camera.beta = DetailCamera.Part_3.beta;
 | 
			
		||||
      //       camera.radius = DetailCamera.Part_3.radius;
 | 
			
		||||
      //       break;
 | 
			
		||||
      //     case 4:
 | 
			
		||||
      //       camera.target = DetailCamera.Part_4.target;
 | 
			
		||||
      //       camera.alpha = DetailCamera.Part_4.alpha;
 | 
			
		||||
      //       camera.beta = DetailCamera.Part_4.beta;
 | 
			
		||||
      //       camera.radius = DetailCamera.Part_4.radius;
 | 
			
		||||
      //       break;
 | 
			
		||||
      //   }
 | 
			
		||||
      // });
 | 
			
		||||
 | 
			
		||||
      return scene;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
@@ -375,52 +260,8 @@ function MybabylonJS({ modelPath }: MybabylonJSProps) {
 | 
			
		||||
    };
 | 
			
		||||
  }, [modelPath]);
 | 
			
		||||
 | 
			
		||||
  // const handleClick1 = () => {
 | 
			
		||||
  //   onMainCamObservable.notifyObservers(1);
 | 
			
		||||
  // };
 | 
			
		||||
  // const handleClick2 = () => {
 | 
			
		||||
  //   onMainCamObservable.notifyObservers(2);
 | 
			
		||||
  // };
 | 
			
		||||
  // const handleClick3 = () => {
 | 
			
		||||
  //   onMainCamObservable.notifyObservers(3);
 | 
			
		||||
  // };
 | 
			
		||||
  // const handleClick4 = () => {
 | 
			
		||||
  //   onMainCamObservable.notifyObservers(4);
 | 
			
		||||
  // };
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    <div style={myStyle}>
 | 
			
		||||
      {/* <ButtonGroup
 | 
			
		||||
        variant="contained"
 | 
			
		||||
        aria-label="outlined button group"
 | 
			
		||||
        className={"btnArea"}
 | 
			
		||||
      >
 | 
			
		||||
        <h2>当前选择: {SelectedMeshName}</h2>
 | 
			
		||||
        <Button
 | 
			
		||||
          sx={{ backgroundColor: "rgba(86, 244, 231, 0.69)" }}
 | 
			
		||||
          onClick={handleClick1}
 | 
			
		||||
        >
 | 
			
		||||
          {intl.get("Part1")}
 | 
			
		||||
        </Button>
 | 
			
		||||
        <Button
 | 
			
		||||
          sx={{ backgroundColor: "rgba(86, 244, 231, 0.69)" }}
 | 
			
		||||
          onClick={handleClick2}
 | 
			
		||||
        >
 | 
			
		||||
          {intl.get("Part2")}
 | 
			
		||||
        </Button>
 | 
			
		||||
        <Button
 | 
			
		||||
          sx={{ backgroundColor: "rgba(86, 244, 231, 0.69)" }}
 | 
			
		||||
          onClick={handleClick3}
 | 
			
		||||
        >
 | 
			
		||||
          {intl.get("Part3")}
 | 
			
		||||
        </Button>
 | 
			
		||||
        <Button
 | 
			
		||||
          sx={{ backgroundColor: "rgba(86, 244, 231, 0.69)" }}
 | 
			
		||||
          onClick={handleClick4}
 | 
			
		||||
        >
 | 
			
		||||
          {intl.get("Part4")}
 | 
			
		||||
        </Button>
 | 
			
		||||
      </ButtonGroup> */}
 | 
			
		||||
      <canvas ref={canvasRef} style={myStyle} />
 | 
			
		||||
    </div>
 | 
			
		||||
  );
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										45
									
								
								src/page/Component/ScrollBoard/index.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										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
									
								
							
							
						
						
									
										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
									
								
							
							
						
						
									
										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
									
								
							
							
						
						
									
										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
									
								
							
							
						
						
									
										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
									
								
							
							
						
						
									
										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;
 | 
			
		||||
}
 | 
			
		||||
@@ -1,16 +1,60 @@
 | 
			
		||||
import TitleBox from "../Component/TitleBox";
 | 
			
		||||
import LineChart from "./LineChart";
 | 
			
		||||
import ScrollBoard from "./../../Component/ScrollBoard";
 | 
			
		||||
import SwitchButton from "../Component/SwitchButton";
 | 
			
		||||
import { useState } from "react";
 | 
			
		||||
function CenterDown() {
 | 
			
		||||
  const nameList = [{ name: "天" }, { name: "周" }, { name: "月" }];
 | 
			
		||||
  const [activeName, setActiveName] = useState<string>(nameList[0].name);
 | 
			
		||||
  const config = {
 | 
			
		||||
    header: ["序号", "报警时间", "报警编码", "设备状态"],
 | 
			
		||||
    headerHeight: 36,
 | 
			
		||||
    rowNum: 6,
 | 
			
		||||
    headerBGC: "rgba(79, 114, 136, 0.3)",
 | 
			
		||||
    oddRowBGC: "rgba(79, 114, 136, 0.3)",
 | 
			
		||||
    evenRowBGC: "rgba(76, 97, 123, 0.1)",
 | 
			
		||||
    columnWidth: [80, 137, 137, 137],
 | 
			
		||||
    data: [
 | 
			
		||||
      ["1", "行1列1", "行1列2", "<span style='color:#FF1E1E'>行1列3</span>"],
 | 
			
		||||
      ["2", "行2列1", "行2列2", "<span style='color:#FF1E1E'>行2列3</span>"],
 | 
			
		||||
      ["3", "行3列1", "行3列2", "<span style='color:#FF1E1E'>行3列3</span>"],
 | 
			
		||||
      ["4", "行4列1", "行4列2", "<span style='color:#FFB40F'>行4列3</span>"],
 | 
			
		||||
      ["5", "行5列1", "行5列2", "<span style='color:#FF1E1E'>行5列3</span>"],
 | 
			
		||||
      ["6", "行6列1", "行6列2", "<span style='color:#FFB40F'>行6列3</span>"],
 | 
			
		||||
      ["7", "行7列1", "行7列2", "<span style='color:#FF1E1E'>行7列3</span>"],
 | 
			
		||||
      ["8", "行8列1", "行8列2", "<span style='color:#FF1E1E'>行8列3</span>"],
 | 
			
		||||
      ["9", "行9列1", "行9列2", "<span style='color:#FF1E1E'>行9列3</span>"],
 | 
			
		||||
      [
 | 
			
		||||
        "10",
 | 
			
		||||
        "行10列1",
 | 
			
		||||
        "行10列2",
 | 
			
		||||
        "<span style='color:#FFB40F'>行10列3</span>",
 | 
			
		||||
      ],
 | 
			
		||||
    ],
 | 
			
		||||
  };
 | 
			
		||||
  return (
 | 
			
		||||
    <div className="center_down flex-row">
 | 
			
		||||
      <div className="center_down_inner flex-col left-box">
 | 
			
		||||
        <TitleBox title={"center_down_left"} />
 | 
			
		||||
        <span className="alarm_num_title">— 报警总数 —</span>
 | 
			
		||||
        <div className="alarm_num">321,343</div>
 | 
			
		||||
        <div style={{ padding: 10, height: "270px" }}>
 | 
			
		||||
          <ScrollBoard
 | 
			
		||||
            config={config}
 | 
			
		||||
            style={{ width: "492px", height: "250px" }}
 | 
			
		||||
          />
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
      {/* 产线成品率 */}
 | 
			
		||||
      <div className="center_down_inner flex-col right_box">
 | 
			
		||||
        <TitleBox title={"center_down_right"} />
 | 
			
		||||
        <div className="left_up_switch">
 | 
			
		||||
          <SwitchButton
 | 
			
		||||
            nameList={nameList}
 | 
			
		||||
            activeName={activeName}
 | 
			
		||||
            setActiveName={setActiveName}
 | 
			
		||||
          />
 | 
			
		||||
        </div>
 | 
			
		||||
        <div className="chart_box">
 | 
			
		||||
          <LineChart />
 | 
			
		||||
        </div>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,8 +1,11 @@
 | 
			
		||||
import LinePageBabylon from "../../../babylonjs/LinePageBabylon";
 | 
			
		||||
import { useParams } from "react-router-dom";
 | 
			
		||||
function CenterUp() {
 | 
			
		||||
  const { LineID } = useParams();
 | 
			
		||||
  const lineID = LineID?.toString() || "1-1";
 | 
			
		||||
  return (
 | 
			
		||||
    <div className="center_up">
 | 
			
		||||
      <LinePageBabylon modelPath={`Line1-2`} />
 | 
			
		||||
      <LinePageBabylon modelPath={`Line${lineID}`} />
 | 
			
		||||
    </div>
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -70,31 +70,44 @@ export default function getOptions() {
 | 
			
		||||
        },
 | 
			
		||||
      },
 | 
			
		||||
    },
 | 
			
		||||
    tooltip: {},
 | 
			
		||||
    tooltip: {
 | 
			
		||||
      trigger: "axis",
 | 
			
		||||
      className: "luoyang-chart-tooltip",
 | 
			
		||||
    },
 | 
			
		||||
    series: [
 | 
			
		||||
      {
 | 
			
		||||
        name: "产线1",
 | 
			
		||||
        type: "line",
 | 
			
		||||
        symbol: "circle",
 | 
			
		||||
        symbolSize: 4,
 | 
			
		||||
        data: [20, 32, 10, 34, 90, 30, 20],
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        name: "产线2",
 | 
			
		||||
        type: "line",
 | 
			
		||||
        symbol: "circle",
 | 
			
		||||
        symbolSize: 4,
 | 
			
		||||
        data: [22, 82, 91, 34, 90, 33, 31],
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        name: "产线3",
 | 
			
		||||
        type: "line",
 | 
			
		||||
        symbol: "circle",
 | 
			
		||||
        symbolSize: 4,
 | 
			
		||||
        data: [50, 32, 20, 54, 19, 33, 41],
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        name: "产线4",
 | 
			
		||||
        type: "line",
 | 
			
		||||
        symbol: "circle",
 | 
			
		||||
        symbolSize: 4,
 | 
			
		||||
        data: [30, 32, 30, 34, 90, 33, 32],
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        name: "产线5",
 | 
			
		||||
        type: "line",
 | 
			
		||||
        symbol: "circle",
 | 
			
		||||
        symbolSize: 4,
 | 
			
		||||
        data: [20, 92, 91, 94, 90, 30, 53],
 | 
			
		||||
      },
 | 
			
		||||
    ],
 | 
			
		||||
 
 | 
			
		||||
@@ -49,7 +49,13 @@ export default function getOptions() {
 | 
			
		||||
        },
 | 
			
		||||
      },
 | 
			
		||||
    },
 | 
			
		||||
    tooltip: {},
 | 
			
		||||
    tooltip: {
 | 
			
		||||
      trigger: "axis",
 | 
			
		||||
      axisPointer: {
 | 
			
		||||
        type: "shadow",
 | 
			
		||||
      },
 | 
			
		||||
      className: "luoyang-chart-tooltip",
 | 
			
		||||
    },
 | 
			
		||||
    series: [
 | 
			
		||||
      {
 | 
			
		||||
        data: [120, 200, 150, 80, 70, 110],
 | 
			
		||||
 
 | 
			
		||||
@@ -1,10 +1,32 @@
 | 
			
		||||
import TitleBox from "../Component/TitleBox";
 | 
			
		||||
import SwitchButton from "../Component/SwitchButton";
 | 
			
		||||
import BarChart from "./BarChart";
 | 
			
		||||
import ScrollBoard from "./../../Component/ScrollBoard";
 | 
			
		||||
import { useState } from "react";
 | 
			
		||||
function LeftDown() {
 | 
			
		||||
  const nameList = [{ name: "表单" }, { name: "柱状" }];
 | 
			
		||||
  const [activeName, setActiveName] = useState<string>(nameList[0].name);
 | 
			
		||||
  const config = {
 | 
			
		||||
    header: ["序号", "缺陷种类", "缺陷数量"],
 | 
			
		||||
    headerHeight: 30,
 | 
			
		||||
    rowNum: 4,
 | 
			
		||||
    headerBGC: "rgba(79, 114, 136, 0.3)",
 | 
			
		||||
    oddRowBGC: "rgba(79, 114, 136, 0.3)",
 | 
			
		||||
    evenRowBGC: "rgba(76, 97, 123, 0.1)",
 | 
			
		||||
    columnWidth: [73, 117, 190],
 | 
			
		||||
    data: [
 | 
			
		||||
      ["行1列1", "行1列2", "行1列3"],
 | 
			
		||||
      ["行2列1", "行2列2", "行2列3"],
 | 
			
		||||
      ["行3列1", "行3列2", "行3列3"],
 | 
			
		||||
      ["行4列1", "行4列2", "行4列3"],
 | 
			
		||||
      ["行5列1", "行5列2", "行5列3"],
 | 
			
		||||
      ["行6列1", "行6列2", "行6列3"],
 | 
			
		||||
      ["行7列1", "行7列2", "行7列3"],
 | 
			
		||||
      ["行8列1", "行8列2", "行8列3"],
 | 
			
		||||
      ["行9列1", "行9列2", "行9列3"],
 | 
			
		||||
      ["行10列1", "行10列2", "行10列3"],
 | 
			
		||||
    ],
 | 
			
		||||
  };
 | 
			
		||||
  return (
 | 
			
		||||
    <div className="left_down">
 | 
			
		||||
      <TitleBox title={"left_down"} />
 | 
			
		||||
@@ -22,7 +44,14 @@ function LeftDown() {
 | 
			
		||||
          <div className="left_down_box2 flex-col" />
 | 
			
		||||
        </div>
 | 
			
		||||
        <div className="left_down_content">
 | 
			
		||||
          {activeName === "表单" ? "表单" : <BarChart />}
 | 
			
		||||
          {activeName === "表单" ? (
 | 
			
		||||
            <ScrollBoard
 | 
			
		||||
              config={config}
 | 
			
		||||
              style={{ width: "380px", height: "150px" }}
 | 
			
		||||
            />
 | 
			
		||||
          ) : (
 | 
			
		||||
            <BarChart />
 | 
			
		||||
          )}
 | 
			
		||||
        </div>
 | 
			
		||||
        <div className="left_down_title flex-row">
 | 
			
		||||
          <div className="left_down_box1 flex-col" />
 | 
			
		||||
@@ -30,7 +59,14 @@ function LeftDown() {
 | 
			
		||||
          <div className="left_down_box2 flex-col" />
 | 
			
		||||
        </div>
 | 
			
		||||
        <div className="left_down_content">
 | 
			
		||||
          {activeName === "表单" ? "表单" : <BarChart />}
 | 
			
		||||
          {activeName === "表单" ? (
 | 
			
		||||
            <ScrollBoard
 | 
			
		||||
              config={config}
 | 
			
		||||
              style={{ width: "380px", height: "150px" }}
 | 
			
		||||
            />
 | 
			
		||||
          ) : (
 | 
			
		||||
            <BarChart />
 | 
			
		||||
          )}
 | 
			
		||||
        </div>
 | 
			
		||||
        <div className="left_down_title flex-row">
 | 
			
		||||
          <div className="left_down_box1 flex-col" />
 | 
			
		||||
@@ -38,7 +74,14 @@ function LeftDown() {
 | 
			
		||||
          <div className="left_down_box2 flex-col" />
 | 
			
		||||
        </div>
 | 
			
		||||
        <div className="left_down_content">
 | 
			
		||||
          {activeName === "表单" ? "表单" : <BarChart />}
 | 
			
		||||
          {activeName === "表单" ? (
 | 
			
		||||
            <ScrollBoard
 | 
			
		||||
              config={config}
 | 
			
		||||
              style={{ width: "380px", height: "150px" }}
 | 
			
		||||
            />
 | 
			
		||||
          ) : (
 | 
			
		||||
            <BarChart />
 | 
			
		||||
          )}
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
 
 | 
			
		||||
@@ -69,7 +69,13 @@ export default function getOptions() {
 | 
			
		||||
        },
 | 
			
		||||
      },
 | 
			
		||||
    },
 | 
			
		||||
    tooltip: {},
 | 
			
		||||
    tooltip: {
 | 
			
		||||
      trigger: "axis",
 | 
			
		||||
      axisPointer: {
 | 
			
		||||
        type: "shadow",
 | 
			
		||||
      },
 | 
			
		||||
      className: "luoyang-chart-tooltip",
 | 
			
		||||
    },
 | 
			
		||||
    dataset: {
 | 
			
		||||
      source: [
 | 
			
		||||
        ["product", "产线1", "产线2", "产线3", "产线4", "产线5"],
 | 
			
		||||
 
 | 
			
		||||
@@ -70,18 +70,25 @@ export default function getOptions() {
 | 
			
		||||
        },
 | 
			
		||||
      },
 | 
			
		||||
    },
 | 
			
		||||
    tooltip: {},
 | 
			
		||||
    series: [
 | 
			
		||||
      {
 | 
			
		||||
        name: "投入",
 | 
			
		||||
        type: "line",
 | 
			
		||||
        symbol: "circle",
 | 
			
		||||
        symbolSize: 4,
 | 
			
		||||
        data: [20, 32, 10, 34, 90, 30, 20],
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        name: "产出",
 | 
			
		||||
        type: "line",
 | 
			
		||||
        symbol: "circle",
 | 
			
		||||
        symbolSize: 4,
 | 
			
		||||
        data: [22, 82, 91, 34, 90, 33, 31],
 | 
			
		||||
      },
 | 
			
		||||
    ],
 | 
			
		||||
    tooltip: {
 | 
			
		||||
      trigger: "axis",
 | 
			
		||||
      className: "luoyang-chart-tooltip",
 | 
			
		||||
    },
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,10 +1,32 @@
 | 
			
		||||
import TitleBox from "../Component/TitleBox";
 | 
			
		||||
import SwitchButton from "../Component/SwitchButton";
 | 
			
		||||
import LineChart from "./LineChart";
 | 
			
		||||
import ScrollBoard from "./../../Component/ScrollBoard";
 | 
			
		||||
import { useState } from "react";
 | 
			
		||||
function RightDown() {
 | 
			
		||||
  const nameList = [{ name: "表单" }, { name: "折线" }];
 | 
			
		||||
  const [activeName, setActiveName] = useState<string>(nameList[0].name);
 | 
			
		||||
  const config = {
 | 
			
		||||
    header: ["时间", "投入数量", "产出数量"],
 | 
			
		||||
    headerHeight: 30,
 | 
			
		||||
    rowNum: 5,
 | 
			
		||||
    headerBGC: "rgba(79, 114, 136, 0.3)",
 | 
			
		||||
    oddRowBGC: "rgba(79, 114, 136, 0.3)",
 | 
			
		||||
    evenRowBGC: "rgba(76, 97, 123, 0.1)",
 | 
			
		||||
    columnWidth: [120, 130, 130],
 | 
			
		||||
    data: [
 | 
			
		||||
      ["行1列1", "行1列2", "行1列3"],
 | 
			
		||||
      ["行2列1", "行2列2", "行2列3"],
 | 
			
		||||
      ["行3列1", "行3列2", "行3列3"],
 | 
			
		||||
      ["行4列1", "行4列2", "行4列3"],
 | 
			
		||||
      ["行5列1", "行5列2", "行5列3"],
 | 
			
		||||
      ["行6列1", "行6列2", "行6列3"],
 | 
			
		||||
      ["行7列1", "行7列2", "行7列3"],
 | 
			
		||||
      ["行8列1", "行8列2", "行8列3"],
 | 
			
		||||
      ["行9列1", "行9列2", "行9列3"],
 | 
			
		||||
      ["行10列1", "行10列2", "行10列3"],
 | 
			
		||||
    ],
 | 
			
		||||
  };
 | 
			
		||||
  return (
 | 
			
		||||
    <div className="right_down">
 | 
			
		||||
      <TitleBox title={"right_down"} />
 | 
			
		||||
@@ -22,7 +44,14 @@ function RightDown() {
 | 
			
		||||
          <div className="left_down_box2 flex-col" />
 | 
			
		||||
        </div>
 | 
			
		||||
        <div className="right_down_content">
 | 
			
		||||
          {activeName === "表单" ? "表单" : <LineChart />}
 | 
			
		||||
          {activeName === "表单" ? (
 | 
			
		||||
            <ScrollBoard
 | 
			
		||||
              config={config}
 | 
			
		||||
              style={{ width: "380px", height: "180px" }}
 | 
			
		||||
            />
 | 
			
		||||
          ) : (
 | 
			
		||||
            <LineChart />
 | 
			
		||||
          )}
 | 
			
		||||
        </div>
 | 
			
		||||
        <div className="left_down_title flex-row">
 | 
			
		||||
          <div className="left_down_box1 flex-col" />
 | 
			
		||||
@@ -30,7 +59,14 @@ function RightDown() {
 | 
			
		||||
          <div className="left_down_box2 flex-col" />
 | 
			
		||||
        </div>
 | 
			
		||||
        <div className="right_down_content">
 | 
			
		||||
          {activeName === "表单" ? "表单" : <LineChart />}
 | 
			
		||||
          {activeName === "表单" ? (
 | 
			
		||||
            <ScrollBoard
 | 
			
		||||
              config={config}
 | 
			
		||||
              style={{ width: "380px", height: "180px" }}
 | 
			
		||||
            />
 | 
			
		||||
          ) : (
 | 
			
		||||
            <LineChart />
 | 
			
		||||
          )}
 | 
			
		||||
        </div>
 | 
			
		||||
        <div className="left_down_title flex-row">
 | 
			
		||||
          <div className="left_down_box1 flex-col" />
 | 
			
		||||
@@ -38,7 +74,14 @@ function RightDown() {
 | 
			
		||||
          <div className="left_down_box2 flex-col" />
 | 
			
		||||
        </div>
 | 
			
		||||
        <div className="right_down_content">
 | 
			
		||||
          {activeName === "表单" ? "表单" : <LineChart />}
 | 
			
		||||
          {activeName === "表单" ? (
 | 
			
		||||
            <ScrollBoard
 | 
			
		||||
              config={config}
 | 
			
		||||
              style={{ width: "380px", height: "180px" }}
 | 
			
		||||
            />
 | 
			
		||||
          ) : (
 | 
			
		||||
            <LineChart />
 | 
			
		||||
          )}
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,8 +1,36 @@
 | 
			
		||||
import TitleBox from "../Component/TitleBox";
 | 
			
		||||
import ScrollBoard from "./../../Component/ScrollBoard";
 | 
			
		||||
function RightUp() {
 | 
			
		||||
  const config = {
 | 
			
		||||
    header: ["产线", "上片数据量", "成品下片数量", "成品下片"],
 | 
			
		||||
    headerHeight: 32,
 | 
			
		||||
    rowNum: 5,
 | 
			
		||||
    headerBGC: "rgba(79, 114, 136, 0.3)",
 | 
			
		||||
    oddRowBGC: "rgba(79, 114, 136, 0.3)",
 | 
			
		||||
    evenRowBGC: "rgba(76, 97, 123, 0.1)",
 | 
			
		||||
    columnWidth: [73, 100, 117, 90],
 | 
			
		||||
    data: [
 | 
			
		||||
      ["1", "行1列1", "行1列2", "行1列3"],
 | 
			
		||||
      ["2", "行2列1", "行2列2", "行2列3"],
 | 
			
		||||
      ["3", "行3列1", "行3列2", "行3列3"],
 | 
			
		||||
      ["4", "行4列1", "行4列2", "行4列3"],
 | 
			
		||||
      ["5", "行5列1", "行5列2", "行5列3"],
 | 
			
		||||
      ["6", "行6列1", "行6列2", "行6列3"],
 | 
			
		||||
      ["7", "行7列1", "行7列2", "行7列3"],
 | 
			
		||||
      ["8", "行8列1", "行8列2", "行8列3"],
 | 
			
		||||
      ["9", "行9列1", "行9列2", "行9列3"],
 | 
			
		||||
      ["10", "行10列1", "行10列2", "行10列3"],
 | 
			
		||||
    ],
 | 
			
		||||
  };
 | 
			
		||||
  return (
 | 
			
		||||
    <div className="right_up">
 | 
			
		||||
      <TitleBox title={"right_up"} />
 | 
			
		||||
      <div style={{ padding: "10px", height: "213px" }}>
 | 
			
		||||
        <ScrollBoard
 | 
			
		||||
          config={config}
 | 
			
		||||
          style={{ width: "380px", height: "193px" }}
 | 
			
		||||
        />
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -76,6 +76,7 @@
 | 
			
		||||
  background: url(../../../public/png/rect/lp_center_down.png) no-repeat;
 | 
			
		||||
  background-size: 100% 100%;
 | 
			
		||||
  background-position: 0 0;
 | 
			
		||||
  position: relative;
 | 
			
		||||
}
 | 
			
		||||
.center_down .left-box {
 | 
			
		||||
  margin-right: 15px;
 | 
			
		||||
@@ -129,6 +130,7 @@
 | 
			
		||||
.left_down_title {
 | 
			
		||||
  height: 18px;
 | 
			
		||||
  justify-content: center;
 | 
			
		||||
  margin-bottom: 4px;
 | 
			
		||||
}
 | 
			
		||||
.left_down_box1 {
 | 
			
		||||
  width: 56px;
 | 
			
		||||
@@ -166,3 +168,22 @@
 | 
			
		||||
  height: 185px;
 | 
			
		||||
  /* padding-bottom: 5px; */
 | 
			
		||||
}
 | 
			
		||||
.dv-scroll-board .header .header-item,
 | 
			
		||||
.dv-scroll-board .rows .ceil {
 | 
			
		||||
  border-right: 1px solid #0d1728;
 | 
			
		||||
}
 | 
			
		||||
.dv-scroll-board .header .header-item:last-child,
 | 
			
		||||
.dv-scroll-board .rows .ceil:last-child {
 | 
			
		||||
  border-right: none;
 | 
			
		||||
  border: none;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.luoyang-chart-tooltip {
 | 
			
		||||
  background: #0a2b4f77 !important;
 | 
			
		||||
  border: none !important;
 | 
			
		||||
  backdrop-filter: blur(12px);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.luoyang-chart-tooltip * {
 | 
			
		||||
  color: #fff !important;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,11 +1,7 @@
 | 
			
		||||
{
 | 
			
		||||
  "compilerOptions": {
 | 
			
		||||
    "target": "es5",
 | 
			
		||||
    "lib": [
 | 
			
		||||
      "dom",
 | 
			
		||||
      "dom.iterable",
 | 
			
		||||
      "esnext"
 | 
			
		||||
    ],
 | 
			
		||||
    "lib": ["dom", "dom.iterable", "esnext"],
 | 
			
		||||
    "allowJs": true,
 | 
			
		||||
    "skipLibCheck": true,
 | 
			
		||||
    "esModuleInterop": true,
 | 
			
		||||
@@ -18,9 +14,8 @@
 | 
			
		||||
    "resolveJsonModule": true,
 | 
			
		||||
    "isolatedModules": true,
 | 
			
		||||
    "noEmit": true,
 | 
			
		||||
    "jsx": "react-jsx"
 | 
			
		||||
    "jsx": "react-jsx",
 | 
			
		||||
    "downlevelIteration": true
 | 
			
		||||
  },
 | 
			
		||||
  "include": [
 | 
			
		||||
    "src"
 | 
			
		||||
  ],
 | 
			
		||||
  "include": ["src"]
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user