5 changed files with 184 additions and 48 deletions
-
41src/pages/measure/components/MeasureAction.tsx
-
128src/pages/measure/components/graph/RealtimeLayer.tsx
-
10src/pages/measure/components/graph/StandardLayer.tsx
-
33src/services/socket.ts
-
20src/services/wsTypes.ts
@ -1,31 +1,105 @@ |
|||||
import { useCallback, useEffect, useRef } from "react"; |
|
||||
|
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: { |
export default function RealtimeLayer(props: { |
||||
width: number; |
|
||||
height: number; |
|
||||
leftPadding: number; |
|
||||
rightPadding: number; |
|
||||
topPadding: number; |
|
||||
bottomPadding: number; |
|
||||
|
width: number; |
||||
|
height: number; |
||||
|
leftPadding: number; |
||||
|
rightPadding: number; |
||||
|
topPadding: number; |
||||
|
bottomPadding: number; |
||||
|
columns: number; |
||||
|
rows: number; |
||||
}) { |
}) { |
||||
const canvasRef = useRef<HTMLCanvasElement | null>(null); |
|
||||
const draw = useCallback((ctx: CanvasRenderingContext2D) => { |
|
||||
// 使用context对象进行绘图
|
|
||||
ctx.fillStyle = "skyblue"; // 设置填充颜色
|
|
||||
ctx.fillRect(50, 50, 150, 100); // 绘制一个矩形
|
|
||||
}, []); |
|
||||
useEffect(() => { |
|
||||
const canvas = canvasRef.current; |
|
||||
if (!canvas) return; |
|
||||
|
|
||||
const context = canvas.getContext("2d"); |
|
||||
if (!context) return; |
|
||||
draw(context); |
|
||||
}, [draw]); |
|
||||
|
|
||||
return ( |
|
||||
<div> |
|
||||
<canvas ref={canvasRef} width={props.width} height={props.height}></canvas> |
|
||||
</div> |
|
||||
); |
|
||||
|
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<HTMLCanvasElement | null>(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; |
||||
|
console.log("-----------------------------------") |
||||
|
ctx.resetTransform(); |
||||
|
ctx.clearRect(0, 0, canvas.width, canvas.height); |
||||
|
ctx.strokeStyle = "blue"; |
||||
|
const xOffset = (xEndPx - xStartPx) / 2; |
||||
|
const yOffset = yStepPx * 2; |
||||
|
ctx.translate(xStartPx + xOffset, yStartPx + yOffset); |
||||
|
} 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); |
||||
|
console.log(pointArr.length); |
||||
|
|
||||
|
const canvas = canvasRef.current; |
||||
|
if (!canvas) return; |
||||
|
|
||||
|
const ctx = canvas.getContext("2d"); |
||||
|
if (!ctx) return; |
||||
|
|
||||
|
// ctx.clearRect(0, 0, canvas.width * 2, canvas.height * 2);
|
||||
|
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); |
||||
|
} |
||||
|
} |
||||
|
// if (pointsPx.length > 1) {
|
||||
|
ctx.stroke(); |
||||
|
// }
|
||||
|
} |
||||
|
}); |
||||
|
wsClient.connect(); |
||||
|
return () => subscription.unsubscribe(); |
||||
|
}, [rtPoints, unitPx, xEndPx, xStartPx, yStartPx, yStepPx]); |
||||
|
|
||||
|
return ( |
||||
|
<div> |
||||
|
<canvas ref={canvasRef} width={props.width} height={props.height}></canvas> |
||||
|
</div> |
||||
|
); |
||||
} |
} |
@ -0,0 +1,20 @@ |
|||||
|
// 开始、停止绘制
|
||||
|
export type TaskState = { |
||||
|
messageType: "EVENT"; |
||||
|
data: { |
||||
|
event: "START_RECORD_SIG" | "END_RECORD_SIG"; |
||||
|
}; |
||||
|
path: "/measurement-task/get-task-state"; |
||||
|
}; |
||||
|
|
||||
|
// 连接上报坐标点
|
||||
|
export type TrackRecordSig = { |
||||
|
messageType: "EVENT"; |
||||
|
data: { |
||||
|
x: number; |
||||
|
y: number; |
||||
|
}; |
||||
|
path: "/measurement-task/profile-record-ctrl-sig"; |
||||
|
}; |
||||
|
|
||||
|
export type Datagram = TrackRecordSig | TaskState; |
Write
Preview
Loading…
Cancel
Save
Reference in new issue