8 changed files with 457 additions and 75 deletions
-
10src/pages/measure/components/MeasureAction.tsx
-
72src/pages/measure/components/SectionalView.tsx
-
31src/pages/measure/components/graph/AreaLayer.tsx
-
88src/pages/measure/components/graph/GridLayer.tsx
-
31src/pages/measure/components/graph/MarkLayer.tsx
-
31src/pages/measure/components/graph/RealtimeLayer.tsx
-
209src/pages/measure/components/graph/StandardLayer.tsx
-
60src/utils/index.ts
@ -1,72 +0,0 @@ |
|||||
import { useCallback, useEffect, useRef } from "react"; |
|
||||
|
|
||||
const primaryLineColor = "rgb(203,213,245)"; |
|
||||
const subLineColor = "rgb(226,231,232)"; |
|
||||
|
|
||||
export default function SectionalView(props: { |
|
||||
width: number; |
|
||||
height: number; |
|
||||
leftPadding: number; |
|
||||
rightPadding: number; |
|
||||
topPadding: number; |
|
||||
bottomPadding: number; |
|
||||
columns: number; |
|
||||
rows: number; |
|
||||
cellNum: number; |
|
||||
}) { |
|
||||
const xStartPx = props.leftPadding; |
|
||||
const xEndPx = props.width - props.rightPadding; |
|
||||
const xStepPx = (props.width - props.leftPadding - props.rightPadding) / props.columns; |
|
||||
const xUnitPx = xStepPx / props.cellNum; |
|
||||
const yStartPx = props.topPadding; |
|
||||
const yEndPx = props.height - props.bottomPadding; |
|
||||
const yStepPx = (props.height - props.topPadding - props.bottomPadding) / props.rows; |
|
||||
const yUnitPx = yStepPx / props.cellNum; |
|
||||
|
|
||||
const canvasRef = useRef<HTMLCanvasElement | null>(null); |
|
||||
const drawGrid = useCallback((ctx: CanvasRenderingContext2D) => { |
|
||||
ctx.beginPath(); |
|
||||
ctx.strokeStyle = subLineColor; |
|
||||
for (let i = 1; i < props.columns * props.cellNum; ++i) { |
|
||||
if (i % props.cellNum === 0) continue; |
|
||||
ctx.moveTo(xStartPx + xUnitPx * i, yStartPx); |
|
||||
ctx.lineTo(xStartPx + xUnitPx * i, yEndPx); |
|
||||
} |
|
||||
for (let j = 1; j < props.rows * props.cellNum; ++j) { |
|
||||
if (j % props.cellNum === 0) continue; |
|
||||
ctx.moveTo(xStartPx, yStartPx + yUnitPx * j); |
|
||||
ctx.lineTo(xEndPx, yStartPx + yUnitPx * j); |
|
||||
} |
|
||||
ctx.stroke(); |
|
||||
|
|
||||
ctx.beginPath(); |
|
||||
ctx.strokeStyle = primaryLineColor; |
|
||||
for (let i = 0; i <= props.columns; ++i) { |
|
||||
ctx.moveTo(xStartPx + xStepPx * i, yStartPx); |
|
||||
ctx.lineTo(xStartPx + xStepPx * i, yEndPx); |
|
||||
} |
|
||||
for (let j = 0; j <= props.rows; ++j) { |
|
||||
ctx.moveTo(xStartPx, yStartPx + yStepPx * j); |
|
||||
ctx.lineTo(xEndPx, yStartPx + yStepPx * j); |
|
||||
} |
|
||||
ctx.stroke(); |
|
||||
},[props.cellNum, props.columns, props.rows, xEndPx, xStartPx, xStepPx, xUnitPx, yEndPx, yStartPx, yStepPx, yUnitPx]) |
|
||||
|
|
||||
useEffect(() => { |
|
||||
// 获取canvas的2D绘图上下文
|
|
||||
const canvas = canvasRef.current; |
|
||||
if (!canvas) return; |
|
||||
|
|
||||
const context = canvas.getContext("2d"); |
|
||||
if (!context) return; |
|
||||
// 使用context对象进行绘图
|
|
||||
drawGrid(context); |
|
||||
}, [drawGrid]); |
|
||||
|
|
||||
|
|
||||
return ( |
|
||||
<div> |
|
||||
<canvas ref={canvasRef} width={props.width} height={props.height}></canvas> |
|
||||
</div> |
|
||||
); |
|
||||
} |
|
@ -0,0 +1,31 @@ |
|||||
|
import { useCallback, useEffect, useRef } from "react"; |
||||
|
|
||||
|
export default function AreaLayer(props: { |
||||
|
width: number; |
||||
|
height: number; |
||||
|
leftPadding: number; |
||||
|
rightPadding: number; |
||||
|
topPadding: number; |
||||
|
bottomPadding: 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> |
||||
|
); |
||||
|
} |
@ -0,0 +1,88 @@ |
|||||
|
import { useCallback, useEffect, useRef } from "react"; |
||||
|
|
||||
|
const primaryLineColor = "rgb(203,213,245)"; |
||||
|
const subLineColor = "rgb(226,231,232)"; |
||||
|
|
||||
|
export default function GridLayer(props: { |
||||
|
width: number; |
||||
|
height: number; |
||||
|
leftPadding: number; |
||||
|
rightPadding: number; |
||||
|
topPadding: number; |
||||
|
bottomPadding: number; |
||||
|
columns: number; |
||||
|
rows: number; |
||||
|
colCellNum: number; |
||||
|
rowCellNum: number; |
||||
|
}) { |
||||
|
const xStartPx = props.leftPadding; |
||||
|
const xEndPx = props.width - props.rightPadding; |
||||
|
const xStepPx = (props.width - props.leftPadding - props.rightPadding) / props.columns; |
||||
|
const xUnitPx = xStepPx / props.colCellNum; |
||||
|
const yStartPx = props.topPadding; |
||||
|
const yEndPx = props.height - props.bottomPadding; |
||||
|
const yStepPx = (props.height - props.topPadding - props.bottomPadding) / props.rows; |
||||
|
const yUnitPx = yStepPx / props.rowCellNum; |
||||
|
|
||||
|
const canvasRef = useRef<HTMLCanvasElement | null>(null); |
||||
|
const drawGrid = useCallback( |
||||
|
(ctx: CanvasRenderingContext2D) => { |
||||
|
ctx.beginPath(); |
||||
|
ctx.strokeStyle = subLineColor; |
||||
|
for (let i = 1; i < props.columns * props.colCellNum; ++i) { |
||||
|
if (i % props.colCellNum === 0) continue; |
||||
|
ctx.moveTo(xStartPx + xUnitPx * i, yStartPx); |
||||
|
ctx.lineTo(xStartPx + xUnitPx * i, yEndPx); |
||||
|
} |
||||
|
for (let j = 1; j < props.rows * props.rowCellNum; ++j) { |
||||
|
if (j % props.rowCellNum === 0) continue; |
||||
|
ctx.moveTo(xStartPx, yStartPx + yUnitPx * j); |
||||
|
ctx.lineTo(xEndPx, yStartPx + yUnitPx * j); |
||||
|
} |
||||
|
ctx.stroke(); |
||||
|
|
||||
|
ctx.beginPath(); |
||||
|
ctx.strokeStyle = primaryLineColor; |
||||
|
for (let i = 0; i <= props.columns; ++i) { |
||||
|
ctx.moveTo(xStartPx + xStepPx * i, yStartPx); |
||||
|
ctx.lineTo(xStartPx + xStepPx * i, yEndPx); |
||||
|
} |
||||
|
for (let j = 0; j <= props.rows; ++j) { |
||||
|
ctx.moveTo(xStartPx, yStartPx + yStepPx * j); |
||||
|
ctx.lineTo(xEndPx, yStartPx + yStepPx * j); |
||||
|
} |
||||
|
ctx.stroke(); |
||||
|
}, |
||||
|
[ |
||||
|
props.colCellNum, |
||||
|
props.columns, |
||||
|
props.rowCellNum, |
||||
|
props.rows, |
||||
|
xEndPx, |
||||
|
xStartPx, |
||||
|
xStepPx, |
||||
|
xUnitPx, |
||||
|
yEndPx, |
||||
|
yStartPx, |
||||
|
yStepPx, |
||||
|
yUnitPx, |
||||
|
] |
||||
|
); |
||||
|
|
||||
|
useEffect(() => { |
||||
|
// 获取canvas的2D绘图上下文
|
||||
|
const canvas = canvasRef.current; |
||||
|
if (!canvas) return; |
||||
|
|
||||
|
const context = canvas.getContext("2d"); |
||||
|
if (!context) return; |
||||
|
// 使用context对象进行绘图
|
||||
|
drawGrid(context); |
||||
|
}, [drawGrid]); |
||||
|
|
||||
|
return ( |
||||
|
<div> |
||||
|
<canvas ref={canvasRef} width={props.width} height={props.height}></canvas> |
||||
|
</div> |
||||
|
); |
||||
|
} |
@ -0,0 +1,31 @@ |
|||||
|
import { useCallback, useEffect, useRef } from "react"; |
||||
|
|
||||
|
export default function MarkLayer(props: { |
||||
|
width: number; |
||||
|
height: number; |
||||
|
leftPadding: number; |
||||
|
rightPadding: number; |
||||
|
topPadding: number; |
||||
|
bottomPadding: 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> |
||||
|
); |
||||
|
} |
@ -0,0 +1,31 @@ |
|||||
|
import { useCallback, useEffect, useRef } from "react"; |
||||
|
|
||||
|
export default function RealtimeLayer(props: { |
||||
|
width: number; |
||||
|
height: number; |
||||
|
leftPadding: number; |
||||
|
rightPadding: number; |
||||
|
topPadding: number; |
||||
|
bottomPadding: 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> |
||||
|
); |
||||
|
} |
@ -0,0 +1,209 @@ |
|||||
|
import { useCallback, useEffect, useRef } from "react"; |
||||
|
import { calculateCircleAbove, calculateCircleBelow } from "../../../../utils"; |
||||
|
|
||||
|
const unitPx = 8; |
||||
|
|
||||
|
const pointsR: [number, number][] = [ |
||||
|
[0, 0], |
||||
|
[9.949007022412, 0.1650166186941], |
||||
|
[25.35, 2.184814802617], |
||||
|
[35.4, 14.20034968551], |
||||
|
[36.31679456414, 32.538841443], |
||||
|
[32.90417417089, 37.53190928715], |
||||
|
[20.0, 41.8333134842], |
||||
|
]; |
||||
|
const pointsL: [number, number][] = [ |
||||
|
[-20.0, 41.83331348425], |
||||
|
[-32.90417417089, 37.53190928715], |
||||
|
[-36.31679456414, 32.538841443], |
||||
|
[-35.4, 14.20034968551], |
||||
|
[-25.35, 2.184814802617], |
||||
|
[-9.949007022412, 0.1650166186941], |
||||
|
[0, 0], |
||||
|
]; |
||||
|
const pointsRight = pointsR.map(p => [p[0] * unitPx, p[1] * unitPx]); |
||||
|
const pointsLeft = pointsL.map(p => [p[0] * unitPx, p[1] * unitPx]); |
||||
|
|
||||
|
export default function StandardLayer(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 canvasRef = useRef<HTMLCanvasElement | null>(null); |
||||
|
|
||||
|
const draw = useCallback( |
||||
|
(ctx: CanvasRenderingContext2D) => { |
||||
|
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); |
||||
|
} |
||||
|
|
||||
|
// 绘制标准线
|
||||
|
ctx.beginPath(); |
||||
|
ctx.strokeStyle = "red"; |
||||
|
// ---- 右侧
|
||||
|
let point0 = pointsRight[0]; |
||||
|
let point1 = pointsRight[1]; |
||||
|
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.anglesForCenter.startAngle, |
||||
|
param.anglesForCenter.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.anglesForCenter.startAngle, |
||||
|
param.anglesForCenter.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.anglesForCenter.startAngle, |
||||
|
param.anglesForCenter.endAngle |
||||
|
); |
||||
|
|
||||
|
point0 = pointsRight[3]; |
||||
|
point1 = pointsRight[4]; |
||||
|
ctx.moveTo(point0[0], point0[1]); |
||||
|
ctx.lineTo(point1[0], point1[1]); |
||||
|
|
||||
|
point0 = pointsRight[4]; |
||||
|
point1 = pointsRight[5]; |
||||
|
ctx.moveTo(point0[0], point0[1]); |
||||
|
param = calculateCircleAbove(point0[0], point0[1], point1[0], point1[1], 5 * unitPx); |
||||
|
console.log(param); |
||||
|
ctx.arc(param.center.x, param.center.y, 5 * unitPx, param.anglesForCenter.startAngle, param.anglesForCenter.endAngle); |
||||
|
|
||||
|
point0 = pointsRight[5]; |
||||
|
point1 = pointsRight[6]; |
||||
|
ctx.moveTo(point0[0], point0[1]); |
||||
|
ctx.lineTo(point1[0], point1[1]); |
||||
|
|
||||
|
// ---- 左侧
|
||||
|
point0 = pointsLeft[0]; |
||||
|
point1 = pointsLeft[1]; |
||||
|
ctx.moveTo(point0[0], point0[1]); |
||||
|
ctx.lineTo(point1[0], point1[1]); |
||||
|
|
||||
|
point0 = pointsLeft[1]; |
||||
|
point1 = pointsLeft[2]; |
||||
|
ctx.moveTo(point0[0], point0[1]); |
||||
|
param = calculateCircleAbove(point0[0], point0[1], point1[0], point1[1], 5 * unitPx); |
||||
|
console.log(param); |
||||
|
ctx.arc(param.center.x, param.center.y, 5 * unitPx, param.anglesForCenter.startAngle, param.anglesForCenter.endAngle); |
||||
|
|
||||
|
point0 = pointsLeft[2]; |
||||
|
point1 = pointsLeft[3]; |
||||
|
ctx.moveTo(point0[0], point0[1]); |
||||
|
ctx.lineTo(point1[0], point1[1]); |
||||
|
|
||||
|
point0 = pointsLeft[3]; |
||||
|
point1 = pointsLeft[4]; |
||||
|
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.anglesForCenter.startAngle, |
||||
|
param.anglesForCenter.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.anglesForCenter.startAngle, |
||||
|
param.anglesForCenter.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.anglesForCenter.startAngle, |
||||
|
param.anglesForCenter.endAngle |
||||
|
); |
||||
|
|
||||
|
ctx.stroke(); |
||||
|
// ctx.fillRect(100, 100, 150, 100); // 绘制一个矩形
|
||||
|
}, |
||||
|
[xEndPx, xStartPx, xStepPx, yEndPx, yStartPx, yStepPx] |
||||
|
); |
||||
|
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> |
||||
|
); |
||||
|
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue