From 47ea9c2ce931555859261f7828c76f89b74b5b73 Mon Sep 17 00:00:00 2001 From: zhangjiming Date: Thu, 6 Mar 2025 18:08:19 +0800 Subject: [PATCH] =?UTF-8?q?=E5=9B=BE=E5=B1=82=E6=B7=BB=E5=8A=A0=E9=9A=90?= =?UTF-8?q?=E8=97=8F/=E6=98=BE=E7=A4=BA=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/measure/components/MeasureAction.tsx | 137 +++++++++++++-------- src/pages/measure/components/graph/AreaLayer.tsx | 3 +- src/pages/measure/components/graph/GridLayer.tsx | 52 +++++--- src/pages/measure/components/graph/MarkLayer.tsx | 3 +- .../measure/components/graph/RealtimeLayer.tsx | 103 ---------------- src/pages/measure/components/graph/ResultLayer.tsx | 104 ++++++++++++++++ .../measure/components/graph/StandardLayer.tsx | 78 ++---------- 7 files changed, 238 insertions(+), 242 deletions(-) delete mode 100644 src/pages/measure/components/graph/RealtimeLayer.tsx create mode 100644 src/pages/measure/components/graph/ResultLayer.tsx diff --git a/src/pages/measure/components/MeasureAction.tsx b/src/pages/measure/components/MeasureAction.tsx index e6e71e4..d76826a 100644 --- a/src/pages/measure/components/MeasureAction.tsx +++ b/src/pages/measure/components/MeasureAction.tsx @@ -1,14 +1,19 @@ -import { Button, Checkbox, CheckboxProps, Radio, RadioChangeEvent, message } from "antd"; +import { Button, Checkbox, CheckboxProps, Switch, RadioChangeEvent, message } from "antd"; import { useState, useEffect } from "react"; import { useNavigate } from "react-router"; -import { startMeasurement } from "../../../services/measure/analysis" +import { startMeasurement } from "../../../services/measure/analysis"; import { createWebSocket, sharedWsUrl } from "../../../services/socket"; import GridLayer from "./graph/GridLayer"; import StandardLayer from "./graph/StandardLayer"; -import RealtimeLayer from "./graph/RealtimeLayer"; +import ResultLayer from "./graph/ResultLayer"; import MarkLayer from "./graph/MarkLayer"; export default function MeasureAction() { + const [showGrid, setShowGrid] = useState(true); + const [showStandard, setShowStandard] = useState(true); + const [showResult, setShowResult] = useState(true); + const [showMark, setShowMark] = useState(true); + const navigate = useNavigate(); const [sideVal, setSideVal] = useState<1 | 2>(1); @@ -22,65 +27,47 @@ export default function MeasureAction() { // navigate("../detail"); }; - useEffect(()=>{ - connectWebpacket() - },[]) + useEffect(() => { + connectWebpacket(); + }, []); - const connectWebpacket = ()=>{ + const connectWebpacket = () => { //连接websocket const wsClient = createWebSocket(sharedWsUrl); - let subscription = wsClient.dataOb.subscribe(data => { - }); + let subscription = wsClient.dataOb.subscribe(data => {}); wsClient.connect(); - } - + }; + const onStart = () => { - startMeasurement().then(res=>{ - console.log('startMeasurement===', res) - message.success('已通知设备开始测量') - }) - } + startMeasurement().then(res => { + console.log("startMeasurement===", res); + message.success("已通知设备开始测量"); + }); + }; + return (
-
- -
- -
-
- +
+
+
+ setShowGrid(checked)} /> + 参考线 +
+
+ setShowStandard(checked)} /> + 标准线 +
+
+ setShowResult(checked)} /> + 对比线 +
+
+ setShowMark(checked)} /> + 角度线 +
-
- + +
+ +
+
+ +
+
+ +
diff --git a/src/pages/measure/components/graph/AreaLayer.tsx b/src/pages/measure/components/graph/AreaLayer.tsx index f7bcede..4314ad3 100644 --- a/src/pages/measure/components/graph/AreaLayer.tsx +++ b/src/pages/measure/components/graph/AreaLayer.tsx @@ -7,6 +7,7 @@ export default function AreaLayer(props: { rightPadding: number; topPadding: number; bottomPadding: number; + visibility: 'hidden' | 'visible'; }) { const canvasRef = useRef(null); const draw = useCallback((ctx: CanvasRenderingContext2D) => { @@ -24,7 +25,7 @@ export default function AreaLayer(props: { }, [draw]); return ( -
+
); diff --git a/src/pages/measure/components/graph/GridLayer.tsx b/src/pages/measure/components/graph/GridLayer.tsx index fb36c71..37b44b7 100644 --- a/src/pages/measure/components/graph/GridLayer.tsx +++ b/src/pages/measure/components/graph/GridLayer.tsx @@ -14,6 +14,7 @@ export default function GridLayer(props: { rows: number; colCellNum: number; rowCellNum: number; + visibility: 'hidden' | 'visible'; }) { const xStartPx = props.leftPadding; const xEndPx = props.width - props.rightPadding; @@ -27,6 +28,9 @@ export default function GridLayer(props: { const canvasRef = useRef(null); const drawGrid = useCallback( (ctx: CanvasRenderingContext2D) => { + ctx.resetTransform(); + ctx.clearRect(0, 0, props.width, props.height); + ctx.beginPath(); ctx.strokeStyle = subLineColor; for (let i = 1; i < props.columns * props.colCellNum; ++i) { @@ -39,7 +43,7 @@ export default function GridLayer(props: { ctx.moveTo(xStartPx, yStartPx + yUnitPx * j); ctx.lineTo(xEndPx, yStartPx + yUnitPx * j); } - ctx.stroke(); + ctx.stroke() ctx.beginPath(); ctx.strokeStyle = primaryLineColor; @@ -51,22 +55,36 @@ export default function GridLayer(props: { ctx.moveTo(xStartPx, yStartPx + yStepPx * j); ctx.lineTo(xEndPx, yStartPx + yStepPx * j); } - ctx.stroke(); + ctx.stroke() + + + ctx.beginPath(); + ctx.strokeStyle = "#999"; + // 偏移原点 + const xOffset = (xEndPx - xStartPx) / 2; + const yOffset = yStepPx * 2; + const yMax = yEndPx - yStartPx - yOffset; + ctx.translate(xStartPx + xOffset, yStartPx + yOffset); + // 绘制原点交叉线 + ctx.moveTo(-xOffset, 0); + ctx.lineTo(xOffset, 0); + ctx.moveTo(0, -yOffset); + ctx.lineTo(0, yMax); + ctx.stroke() + + // 绘制x轴y轴 单位数值 + ctx.beginPath(); + ctx.fillStyle = "#333333"; + ctx.textAlign = "center"; + ctx.font = "normal 14px system"; + for (let index = -4; index < 5; index++) { + ctx.fillText((index * 10).toString(), xStepPx * index, yMax + 20); + } + for (let index = -1; index < 5; index++) { + ctx.fillText((-index * 10).toString(), -xOffset - (index > 0 ? 18 : 14), yStepPx * index + 4); + } }, - [ - props.colCellNum, - props.columns, - props.rowCellNum, - props.rows, - xEndPx, - xStartPx, - xStepPx, - xUnitPx, - yEndPx, - yStartPx, - yStepPx, - yUnitPx, - ] + [props.colCellNum, props.columns, props.height, props.rowCellNum, props.rows, props.width, xEndPx, xStartPx, xStepPx, xUnitPx, yEndPx, yStartPx, yStepPx, yUnitPx] ); useEffect(() => { @@ -81,7 +99,7 @@ export default function GridLayer(props: { }, [drawGrid]); return ( -
+
); diff --git a/src/pages/measure/components/graph/MarkLayer.tsx b/src/pages/measure/components/graph/MarkLayer.tsx index 560e814..f155894 100644 --- a/src/pages/measure/components/graph/MarkLayer.tsx +++ b/src/pages/measure/components/graph/MarkLayer.tsx @@ -17,6 +17,7 @@ export default function MarkLayer(props: { bottomPadding: number; columns: number; rows: number; + visibility: 'hidden' | 'visible'; }) { const xStartPx = props.leftPadding; const xEndPx = props.width - props.rightPadding; @@ -81,7 +82,7 @@ export default function MarkLayer(props: { }, [draw]); return ( -
+
); diff --git a/src/pages/measure/components/graph/RealtimeLayer.tsx b/src/pages/measure/components/graph/RealtimeLayer.tsx deleted file mode 100644 index 387c5b2..0000000 --- a/src/pages/measure/components/graph/RealtimeLayer.tsx +++ /dev/null @@ -1,103 +0,0 @@ -import { useCallback, useEffect, useRef, useState } from "react"; -import points from "../../../../utils/measure.json"; -import { createWebSocket, sharedWsUrl } from "../../../../services/socket"; -const wsClient = createWebSocket(sharedWsUrl); -console.log(sharedWsUrl); - -const pointArr: { x: number; y: number }[] = []; - -export default function RealtimeLayer(props: { - width: number; - height: number; - leftPadding: number; - rightPadding: number; - topPadding: number; - bottomPadding: number; - columns: number; - rows: number; -}) { - const xStartPx = props.leftPadding; - const xEndPx = props.width - props.rightPadding; - const xStepPx = (props.width - props.leftPadding - props.rightPadding) / props.columns; - const yStartPx = props.topPadding; - // const yEndPx = props.height - props.bottomPadding; - const yStepPx = (props.height - props.topPadding - props.bottomPadding) / props.rows; - - const unitPx = xStepPx / 10; - const pointsPx = points.map(p => ({ x: p.x * unitPx, y: p.y * unitPx + 4 })); // 特意偏移 - - const canvasRef = useRef(null); - - const [rtPoints, setRtPoints] = useState<{ x: number; y: number }[]>([]); - - // const draw = useCallback( - // (ctx: CanvasRenderingContext2D) => { - // for (let idx = 0; idx < pointsPx.length; idx++) { - // if (idx === 0) { - // ctx.moveTo(pointsPx[idx].x, pointsPx[idx].y); - // } else { - // ctx.lineTo(pointsPx[idx].x, pointsPx[idx].y); - // } - // } - // ctx.stroke(); - // }, - // [pointsPx, xEndPx, xStartPx, yStartPx, yStepPx] - // ); - - useEffect(() => { - const subscription = wsClient.dataOb.subscribe(data => { - if (data.path === "/measurement-task/get-task-state") { - const canvas = canvasRef.current; - if (!canvas) return; - - const ctx = canvas.getContext("2d"); - if (!ctx) return; - - if (data.data.event === "START_RECORD_SIG") { - // setRtPoints([]); - pointArr.length = 0; - ctx.resetTransform(); - ctx.clearRect(0, 0, canvas.width, canvas.height); - setTimeout(() => { - ctx.strokeStyle = "blue"; - const xOffset = (xEndPx - xStartPx) / 2; - const yOffset = yStepPx * 2; - ctx.translate(xStartPx + xOffset, yStartPx + yOffset); - ctx.beginPath(); - }, 0); - } else if (data.data.event === "END_RECORD_SIG") { - // - } - } else if (data.path === "/measurement-task/profile-record-ctrl-sig") { - // console.log(data.data); - // setRtPoints(rtPoints.concat([data.data])); - pointArr.push(data.data); - - const canvas = canvasRef.current; - if (!canvas) return; - - const ctx = canvas.getContext("2d"); - if (!ctx) return; - - const pointsPx = pointArr.map(p => ({ x: p.x * unitPx, y: p.y * unitPx })); - - for (let idx = 0; idx < pointsPx.length; idx++) { - if (idx === 0) { - ctx.moveTo(pointsPx[idx].x, pointsPx[idx].y); - } else { - ctx.lineTo(pointsPx[idx].x, pointsPx[idx].y); - } - } - ctx.stroke(); - } - }); - wsClient.connect(); - return () => subscription.unsubscribe(); - }, [rtPoints, unitPx, xEndPx, xStartPx, yStartPx, yStepPx]); - - return ( -
- -
- ); -} diff --git a/src/pages/measure/components/graph/ResultLayer.tsx b/src/pages/measure/components/graph/ResultLayer.tsx new file mode 100644 index 0000000..c5ba795 --- /dev/null +++ b/src/pages/measure/components/graph/ResultLayer.tsx @@ -0,0 +1,104 @@ +import { useCallback, useEffect, useRef, useState } from "react"; +import points from "../../../../utils/measure.json"; +import { createWebSocket, sharedWsUrl } from "../../../../services/socket"; +const wsClient = createWebSocket(sharedWsUrl); +console.log(sharedWsUrl); + +const pointArr: { x: number; y: number }[] = []; + +export default function ResultLayer(props: { + width: number; + height: number; + leftPadding: number; + rightPadding: number; + topPadding: number; + bottomPadding: number; + columns: number; + rows: number; + visibility: 'hidden' | 'visible'; +}) { + const xStartPx = props.leftPadding; + const xEndPx = props.width - props.rightPadding; + const xStepPx = (props.width - props.leftPadding - props.rightPadding) / props.columns; + const yStartPx = props.topPadding; + // const yEndPx = props.height - props.bottomPadding; + const yStepPx = (props.height - props.topPadding - props.bottomPadding) / props.rows; + + const unitPx = xStepPx / 10; + const pointsPx = points.map(p => ({ x: p.x * unitPx, y: p.y * unitPx + 4 })); // 特意偏移 + + const canvasRef = useRef(null); + + const [rtPoints, setRtPoints] = useState<{ x: number; y: number }[]>([]); + + // const draw = useCallback( + // (ctx: CanvasRenderingContext2D) => { + // for (let idx = 0; idx < pointsPx.length; idx++) { + // if (idx === 0) { + // ctx.moveTo(pointsPx[idx].x, pointsPx[idx].y); + // } else { + // ctx.lineTo(pointsPx[idx].x, pointsPx[idx].y); + // } + // } + // ctx.stroke(); + // }, + // [pointsPx, xEndPx, xStartPx, yStartPx, yStepPx] + // ); + + useEffect(() => { + const subscription = wsClient.dataOb.subscribe(data => { + if (data.path === "/measurement-task/get-task-state") { + const canvas = canvasRef.current; + if (!canvas) return; + + const ctx = canvas.getContext("2d"); + if (!ctx) return; + + if (data.data.event === "START_RECORD_SIG") { + // setRtPoints([]); + pointArr.length = 0; + ctx.resetTransform(); + ctx.clearRect(0, 0, canvas.width, canvas.height); + setTimeout(() => { + ctx.strokeStyle = "blue"; + const xOffset = (xEndPx - xStartPx) / 2; + const yOffset = yStepPx * 2; + ctx.translate(xStartPx + xOffset, yStartPx + yOffset); + ctx.beginPath(); + }, 0); + } else if (data.data.event === "END_RECORD_SIG") { + // + } + } else if (data.path === "/measurement-task/profile-record-ctrl-sig") { + // console.log(data.data); + // setRtPoints(rtPoints.concat([data.data])); + pointArr.push(data.data); + + const canvas = canvasRef.current; + if (!canvas) return; + + const ctx = canvas.getContext("2d"); + if (!ctx) return; + + const pointsPx = pointArr.map(p => ({ x: p.x * unitPx, y: p.y * unitPx })); + + for (let idx = 0; idx < pointsPx.length; idx++) { + if (idx === 0) { + ctx.moveTo(pointsPx[idx].x, pointsPx[idx].y+6); + } else { + ctx.lineTo(pointsPx[idx].x, pointsPx[idx].y+6); + } + } + ctx.stroke(); + } + }); + wsClient.connect(); + return () => subscription.unsubscribe(); + }, [rtPoints, unitPx, xEndPx, xStartPx, yStartPx, yStepPx]); + + return ( +
+ +
+ ); +} diff --git a/src/pages/measure/components/graph/StandardLayer.tsx b/src/pages/measure/components/graph/StandardLayer.tsx index 6c6a325..216e99a 100644 --- a/src/pages/measure/components/graph/StandardLayer.tsx +++ b/src/pages/measure/components/graph/StandardLayer.tsx @@ -29,6 +29,7 @@ export default function StandardLayer(props: { bottomPadding: number; columns: number; rows: number; + visibility: "hidden" | "visible"; }) { const xStartPx = props.leftPadding; const xEndPx = props.width - props.rightPadding; @@ -45,33 +46,14 @@ export default function StandardLayer(props: { const draw = useCallback( (ctx: CanvasRenderingContext2D) => { - ctx.strokeStyle = "#999"; + ctx.resetTransform(); + ctx.clearRect(0, 0, props.width, props.height); // 偏移原点 const xOffset = (xEndPx - xStartPx) / 2; const yOffset = yStepPx * 2; - const yMax = yEndPx - yStartPx - yOffset; ctx.translate(xStartPx + xOffset, yStartPx + yOffset); - // 绘制原点交叉线 - ctx.moveTo(-xOffset, 0); - ctx.lineTo(xOffset, 0); - ctx.moveTo(0, -yOffset); - ctx.lineTo(0, yMax); - ctx.stroke(); - - // 绘制x轴y轴 单位数值 - ctx.beginPath(); - ctx.fillStyle = "#333333"; - ctx.textAlign = "center"; - ctx.font = "normal 14px system"; - for (let index = -4; index < 5; index++) { - ctx.fillText((index * 10).toString(), xStepPx * index, yMax + 20); - } - for (let index = -1; index < 5; index++) { - ctx.fillText((-index * 10).toString(), -xOffset - (index > 0 ? 18 : 14), yStepPx * index + 4); - } - + // 绘制标准线 - ctx.beginPath(); ctx.strokeStyle = "red"; // ---- 右侧 (从上到下) let point0 = pointsRight[0]; @@ -79,39 +61,21 @@ export default function StandardLayer(props: { ctx.moveTo(point0[0], point0[1]); let param = calculateCircleBelow(point0[0], point0[1], point1[0], point1[1], 300 * unitPx); // console.log(param); - ctx.arc( - param.center.x, - param.center.y, - 300 * unitPx, - param.angles.startAngle, - param.angles.endAngle - ); + ctx.arc(param.center.x, param.center.y, 300 * unitPx, param.angles.startAngle, param.angles.endAngle); point0 = pointsRight[1]; point1 = pointsRight[2]; ctx.moveTo(point0[0], point0[1]); param = calculateCircleBelow(point0[0], point0[1], point1[0], point1[1], 80 * unitPx); // console.log(param); - ctx.arc( - param.center.x, - param.center.y, - 80 * unitPx, - param.angles.startAngle, - param.angles.endAngle - ); + ctx.arc(param.center.x, param.center.y, 80 * unitPx, param.angles.startAngle, param.angles.endAngle); point0 = pointsRight[2]; point1 = pointsRight[3]; ctx.moveTo(point0[0], point0[1]); param = calculateCircleBelow(point0[0], point0[1], point1[0], point1[1], 13 * unitPx); // console.log(param); - ctx.arc( - param.center.x, - param.center.y, - 13 * unitPx, - param.angles.startAngle, - param.angles.endAngle - ); + ctx.arc(param.center.x, param.center.y, 13 * unitPx, param.angles.startAngle, param.angles.endAngle); point0 = pointsRight[3]; point1 = pointsRight[4]; @@ -153,43 +117,25 @@ export default function StandardLayer(props: { ctx.moveTo(point0[0], point0[1]); param = calculateCircleBelow(point0[0], point0[1], point1[0], point1[1], 13 * unitPx); // console.log(param); - ctx.arc( - param.center.x, - param.center.y, - 13 * unitPx, - param.angles.startAngle, - param.angles.endAngle - ); + ctx.arc(param.center.x, param.center.y, 13 * unitPx, param.angles.startAngle, param.angles.endAngle); point0 = pointsLeft[4]; point1 = pointsLeft[5]; ctx.moveTo(point0[0], point0[1]); param = calculateCircleBelow(point0[0], point0[1], point1[0], point1[1], 80 * unitPx); // console.log(param); - ctx.arc( - param.center.x, - param.center.y, - 80 * unitPx, - param.angles.startAngle, - param.angles.endAngle - ); + ctx.arc(param.center.x, param.center.y, 80 * unitPx, param.angles.startAngle, param.angles.endAngle); point0 = pointsLeft[5]; point1 = pointsLeft[6]; ctx.moveTo(point0[0], point0[1]); param = calculateCircleBelow(point0[0], point0[1], point1[0], point1[1], 300 * unitPx); // console.log(param); - ctx.arc( - param.center.x, - param.center.y, - 300 * unitPx, - param.angles.startAngle, - param.angles.endAngle - ); + ctx.arc(param.center.x, param.center.y, 300 * unitPx, param.angles.startAngle, param.angles.endAngle); ctx.stroke(); }, - [pointsLeft, pointsRight, unitPx, xEndPx, xStartPx, xStepPx, yEndPx, yStartPx, yStepPx] + [pointsLeft, pointsRight, props.height, props.width, unitPx, xEndPx, xStartPx, yStartPx, yStepPx] ); useEffect(() => { const canvas = canvasRef.current; @@ -201,7 +147,7 @@ export default function StandardLayer(props: { }, [draw]); return ( -
+
);