775 lines
20 KiB
Vue
775 lines
20 KiB
Vue
<template>
|
||
<div>
|
||
<!-- <button @click="moveCanvas('left')">左边-左移</button>
|
||
<button @click="moveCanvas('right')">左边-右移</button>-->
|
||
<sb :-isfd="FD"/>
|
||
<div class="container">
|
||
<div id="canvas-container">
|
||
<canvas ref="leftCanvas" id="leftCanvas" width="21" height="1140"></canvas>
|
||
<canvas ref="bottomCanvas" id="bottomCanvas" width="1140" height="1140"></canvas>
|
||
<canvas
|
||
ref="topCanvas"
|
||
id="topCanvas"
|
||
width="1140"
|
||
height="1140"
|
||
@mousedown="handleMouseDown($event, 'L')"
|
||
></canvas>
|
||
</div>
|
||
|
||
<div id="canvas-container1">
|
||
<canvas ref="rightCanvas" id="rightCanvas" width="21" height="1140"></canvas>
|
||
<canvas ref="bottomCanvas1" id="bottomCanvas1" width="1140" height="1140"></canvas>
|
||
<canvas
|
||
ref="topCanvas1"
|
||
id="topCanvas1"
|
||
width="1140"
|
||
height="1140"
|
||
@mousedown="handleMouseDown($event, 'R')"
|
||
></canvas>
|
||
</div>
|
||
</div>
|
||
<span class="myrtip"
|
||
>{{ ' 走速:' + convert(suduratio, 0) + 'mm/s ' }}
|
||
{{ ' 振幅:' + convert(lineratio, 1) + 'mm/mv ' }} {{ ' 报告模式:6X2' }}</span
|
||
>
|
||
<div @click="preventClick">
|
||
<el-slider
|
||
v-model="sliderValue"
|
||
:min="0"
|
||
:max="50"
|
||
:step="1"
|
||
@input="handleSliderChange"
|
||
:show-tooltip="false"
|
||
/>
|
||
</div>
|
||
|
||
</div>
|
||
<!--纠错功能-->
|
||
<el-dialog v-model="isdialog" title="导联纠错" width="600" @close="close">
|
||
<div>
|
||
<el-checkbox-group v-model="transfer" :min="0" :max="2" class="mycheckbox-group">
|
||
<el-checkbox
|
||
v-for="city in transferleads"
|
||
:key="city"
|
||
:label="city"
|
||
:value="city"
|
||
class="mycheckbox-item"
|
||
@change="checkboxchage"
|
||
>
|
||
{{ city }}
|
||
</el-checkbox>
|
||
</el-checkbox-group>
|
||
</div>
|
||
<div style="margin-top: 10px">
|
||
<el-button type="primary" @click="clickdl" :disabled="checkes">交换导联</el-button>
|
||
<el-button type="primary" @click="recovery()">恢复正常</el-button>
|
||
</div>
|
||
</el-dialog>
|
||
</template>
|
||
|
||
<script setup>
|
||
import { ref, reactive, onMounted } from 'vue'
|
||
import { number } from 'vue-types'
|
||
import Magnifier from './ECGFD.vue'
|
||
import sb from './ECGSB.vue'
|
||
import BB from './ECGBB.vue'
|
||
|
||
//读取出来的json
|
||
const text = ref()
|
||
const sliderValue = ref(0) // 初始化滑块值
|
||
//给父组件回传值
|
||
const emits = defineEmits(['update:value'])
|
||
const lineratio1 = ref(0.05) //画线的系数 振幅
|
||
const previousValue = ref(0) // 记录上一个滑块值
|
||
const swipeDirection = ref('') // 用于存储滑动方向
|
||
// 响应式引用
|
||
const leftCanvas = ref(null)
|
||
const rightCanvas = ref(null)
|
||
const bottomCanvas = ref(null)
|
||
const bottomCanvas1 = ref(null)
|
||
const topCanvas = ref(null)
|
||
const topCanvas1 = ref(null)
|
||
const url = ref()
|
||
/*鼠标绘制相关*/
|
||
const ctx = ref(null)
|
||
const isVertical = ref(false) // 控制线条类型,true 为竖直,false 为水平
|
||
const lastPoint = ref(null) // 用于存储上一个点的坐标
|
||
const isdialog = ref(false) //用于开启纠错
|
||
const transfer = ref() //纠错导联 值
|
||
|
||
const checkes = ref(true) //控制导联交换按钮是否可用
|
||
|
||
// 响应式数据
|
||
const beatArray1 = ref([])
|
||
const beatArray2 = ref([]) //备份数据
|
||
let offset = 0
|
||
const spacing = 20
|
||
|
||
const heightoff=ref(0)//心电图的偏移量 高度变化的时候
|
||
const FD=ref(false)
|
||
|
||
function handleMouseDown(event, type) {
|
||
if (type === 'L') {
|
||
ctx.value = topCanvas.value.getContext('2d')
|
||
} else if (type === 'R') {
|
||
ctx.value = topCanvas1.value.getContext('2d')
|
||
}
|
||
|
||
if (infoParams.Ismeasure !== 1) {
|
||
return
|
||
}
|
||
const rect =
|
||
type === 'L'
|
||
? topCanvas.value.getBoundingClientRect()
|
||
: topCanvas1.value.getBoundingClientRect()
|
||
const x = event.clientX - rect.left
|
||
const y = event.clientY - rect.top
|
||
|
||
if (lastPoint.value) {
|
||
// 如果已经有一个点被记录,那么使用这个新点和上一个点绘制线条
|
||
drawLineAndDistance(lastPoint.value, { x, y })
|
||
lastPoint.value = null // 重置上一个点
|
||
} else {
|
||
// 记录这个点作为上一个点
|
||
lastPoint.value = { x, y }
|
||
}
|
||
}
|
||
|
||
function calculateDistance(x1, y1, x2, y2) {
|
||
return Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2))
|
||
}
|
||
|
||
function drawLineAndDistance(point1, point2) {
|
||
//ctx.value.clearRect(0, 0, topCanvas.value.width, topCanvas.value.height); // 清除画布
|
||
|
||
//竖线
|
||
if (Math.abs(point2.x - point1.x) <= 20) {
|
||
point2.x = point1.x
|
||
lineTo(point1.x, point1.y, point2.x, point2.y, 1)
|
||
} else if (Math.abs(point2.y - point1.y) <= 20) {
|
||
//横
|
||
point2.y = point1.y
|
||
lineTo(point1.x, point1.y, point2.x, point2.y, 0)
|
||
} else {
|
||
lastPoint.value = null
|
||
}
|
||
}
|
||
|
||
function lineTo(x, y, x1, y1, type) {
|
||
// 绘制两个点
|
||
ctx.value.fillStyle = 'black'
|
||
ctx.value.beginPath()
|
||
ctx.value.arc(x, y, 1, 0, 2 * Math.PI)
|
||
ctx.value.fill()
|
||
ctx.value.beginPath()
|
||
ctx.value.arc(x1, y1, 1, 0, 2 * Math.PI)
|
||
ctx.value.fill()
|
||
|
||
// 绘制直线
|
||
ctx.value.beginPath()
|
||
ctx.value.moveTo(x, y)
|
||
ctx.value.lineTo(x1, y1)
|
||
ctx.value.strokeStyle = 'black'
|
||
ctx.value.lineWidth = 1
|
||
ctx.value.stroke()
|
||
|
||
// 计算并绘制距离文本
|
||
const distance = calculateDistance(x, y, x1, y1)
|
||
const ms = (25.4 / 96) * (25 / 1000) * distance
|
||
ctx.value.font = '11px Arial'
|
||
ctx.value.fillStyle = 'black'
|
||
if (type === 1) {
|
||
ctx.value.fillText(`距离: ${ms.toFixed(2)}ms`, x + 5, y + 30)
|
||
} else {
|
||
ctx.value.fillText(`距离: ${ms.toFixed(2)}ms`, x + 10, y - 10)
|
||
}
|
||
}
|
||
|
||
/*鼠标绘制相关*/
|
||
|
||
const handleSliderChange = (value) => {
|
||
// 计算当前值与上一次值之间的差值
|
||
const difference = value - previousValue.value
|
||
const swipeDifference = Math.abs(difference)
|
||
console.log('滑动差值' + swipeDifference)
|
||
if (value > previousValue.value) {
|
||
swipeDirection.value = '右滑' // 向右滑动
|
||
moveCanvas('left', swipeDifference)
|
||
} else if (value < previousValue.value) {
|
||
swipeDirection.value = '左滑' // 向左滑动
|
||
moveCanvas('right', swipeDifference)
|
||
} else {
|
||
swipeDirection.value = '未滑动' // 没有滑动
|
||
}
|
||
previousValue.value = value // 更新上一个值
|
||
console.log('滑块值改变为:', value)
|
||
}
|
||
|
||
//渲染组件后执行
|
||
onMounted(async () => {
|
||
console.log('挂载完成')
|
||
// topCanvas.value = document.getElementById('topCanvas');
|
||
})
|
||
|
||
nextTick(() => {
|
||
/* 计算宽度和高度*/
|
||
var canvasContainer = document.getElementById('canvas-container')
|
||
var canvasContainer1 = document.getElementById('canvas-container1')
|
||
|
||
var leftCanvas = document.getElementById('leftCanvas')
|
||
// 获取元素的计算后的样式
|
||
var style = window.getComputedStyle(canvasContainer)
|
||
// 获取元素的计算后的样式
|
||
var leftCanvasstyle = window.getComputedStyle(leftCanvas)
|
||
|
||
// 获取宽度
|
||
var widthPercentage = style.width
|
||
|
||
//获取高度
|
||
var heightPercentage = style.height
|
||
|
||
var widthInPixels = canvasContainer.offsetWidth
|
||
var heightInPixels = canvasContainer.offsetHeight
|
||
|
||
// 宽度除以 20 并取整
|
||
var adjustedWidth = widthInPixels / 20
|
||
var adjustedheight = heightInPixels / 20
|
||
// 判断 adjustedWidth 是否为整数
|
||
if (Number.isInteger(adjustedWidth)) {
|
||
canvasContainer.style.width = widthInPixels + 'px'
|
||
} else {
|
||
const integer = Math.round(adjustedWidth)
|
||
const awidth = integer * 20
|
||
canvasContainer.style.width = awidth - 20 + 'px'
|
||
canvasContainer1.style.width = awidth - 20 + 'px'
|
||
console.log('adjustedWidth 不是整数')
|
||
}
|
||
if (Number.isInteger(adjustedheight)) {
|
||
canvasContainer.style.height = heightInPixels + 'px'
|
||
leftCanvas.height = heightInPixels + 'px'
|
||
} else {
|
||
const integer = Math.round(adjustedheight)
|
||
const ahe = integer * 20
|
||
canvasContainer.style.height = ahe - 118 + 'px'
|
||
canvasContainer1.style.height = ahe - 118 + 'px'
|
||
leftCanvas.height = ahe - 118
|
||
heightoff.value=(ahe -118)/6
|
||
}
|
||
fetchData()
|
||
})
|
||
|
||
// 定义异步方法
|
||
const fetchData = async () => {
|
||
try {
|
||
text.value = await fetchFileContent(infoParams.jsonurl)
|
||
handleFileChange()
|
||
Bottom()
|
||
// console.log('获取到的数据:', text.value);
|
||
} catch (error) {
|
||
console.error('获取数据时出错:', error)
|
||
}
|
||
}
|
||
|
||
const inputSlider = (value) => {
|
||
setScrollTop(value)
|
||
}
|
||
const formatTooltip = (value) => {
|
||
return `${value} px`
|
||
}
|
||
async function fetchFileContent(url) {
|
||
try {
|
||
const response = await fetch(url)
|
||
if (!response.ok) {
|
||
throw new Error('网络响应不是 ok')
|
||
}
|
||
return await response.text() // 返回文本内容
|
||
} catch (error) {
|
||
console.error('获取文件内容时出错:', error)
|
||
throw error // 抛出错误以便调用者可以处理
|
||
}
|
||
}
|
||
///接受参数
|
||
const infoParams = defineProps({
|
||
jsonurl: String,
|
||
examId: String,
|
||
Isgrid: Number,
|
||
Ismeasure: Number,
|
||
Isfd: Boolean,
|
||
lineratio: Number,
|
||
suduratio: Number,
|
||
isrefresh: Boolean,
|
||
iscorrect: Boolean
|
||
})
|
||
|
||
// 监听多个值的变化
|
||
watch(
|
||
[
|
||
() => infoParams.Isgrid,
|
||
() => infoParams.Ismeasure,
|
||
() => infoParams.lineratio,
|
||
() => infoParams.suduratio,
|
||
() => infoParams.isrefresh,
|
||
() => infoParams.iscorrect,
|
||
()=>infoParams.Isfd
|
||
],
|
||
(
|
||
[newIsGridValue, newAnotherValue, newlineratio, newsuduratio, newisrefresh, newiniscorrect,newfd],
|
||
[oldIsGridView, oldAnotherValue, oldlineratio, oldsuduratio, oldisrefresh, oldiscorrect,oldds]
|
||
) => {
|
||
// 检查 isGrid 是否发生变化
|
||
if (newIsGridValue !== oldIsGridView) {
|
||
// 值发送变化的时候 重新绘制 先清除画布
|
||
Repaint()
|
||
}
|
||
// 检查 anotherValue 是否发生变化
|
||
if (newAnotherValue !== oldAnotherValue) {
|
||
// 是否开启测量
|
||
}
|
||
//振幅
|
||
if (newlineratio !== oldlineratio) {
|
||
Repaint()
|
||
}
|
||
//走速
|
||
if (newsuduratio !== oldsuduratio) {
|
||
Repaint()
|
||
}
|
||
//刷新
|
||
if (newisrefresh !== oldisrefresh) {
|
||
console.log(newisrefresh)
|
||
Repaint()
|
||
}
|
||
//
|
||
if (newiniscorrect !== oldiscorrect) {
|
||
isdialog.value = newiniscorrect
|
||
}
|
||
if(newfd!==oldds)
|
||
{
|
||
FD.value=newfd
|
||
console.log(FD.value)
|
||
}
|
||
}
|
||
)
|
||
//恢复导联
|
||
function recovery() {
|
||
transfer.value = []
|
||
beatArray1.value = beatArray2.value.slice()
|
||
Repaint()
|
||
}
|
||
|
||
//交换导联按钮
|
||
function checkboxchage() {
|
||
checkes.value = transfer.value.length === 2 ? false : true
|
||
}
|
||
//交换导联
|
||
function clickdl() {
|
||
const one = transfer.value[0]
|
||
const two = transfer.value[1]
|
||
const oneindex = transferleads.indexOf(one)
|
||
const twoindex = transferleads.indexOf(two)
|
||
swapElements(oneindex, twoindex)
|
||
Repaint()
|
||
}
|
||
|
||
// 定义一个方法来交换数组中的两个元素
|
||
const swapElements = (index1, index2) => {
|
||
// 检查索引是否有效
|
||
if (
|
||
index1 < 0 ||
|
||
index2 < 0 ||
|
||
index1 >= beatArray1.value.length ||
|
||
index2 >= beatArray1.value.length
|
||
) {
|
||
console.log('索引超出数组范围')
|
||
return
|
||
}
|
||
// 交换元素
|
||
const temp = beatArray1.value[index1]
|
||
beatArray1.value[index1] = beatArray1.value[index2]
|
||
beatArray1.value[index2] = temp
|
||
}
|
||
|
||
//纠错
|
||
function close() {
|
||
isdialog.value = false
|
||
transfer.value = []
|
||
emits('update:value', isdialog.value)
|
||
}
|
||
|
||
// 定义一个对象来存储命令值和对应的比例文本
|
||
const lineratioMap = {
|
||
0.012: '2.5',
|
||
0.025: '5',
|
||
0.05: '10',
|
||
0.1: '20',
|
||
0.2: '40'
|
||
}
|
||
const suduratioMap = {
|
||
0.2: '5',
|
||
0.4: '10',
|
||
0.5: '12.5',
|
||
1: '25',
|
||
2: '50'
|
||
}
|
||
function convert(command, type) {
|
||
if (type === 0) {
|
||
return suduratioMap[command] || null
|
||
} else {
|
||
return lineratioMap[command] || null
|
||
}
|
||
}
|
||
|
||
// 刷新 重绘
|
||
function Repaint() {
|
||
eliminate(leftCanvas.value)
|
||
eliminate(rightCanvas.value)
|
||
eliminate(bottomCanvas.value)
|
||
eliminate(bottomCanvas1.value)
|
||
eliminate(topCanvas.value)
|
||
eliminate(topCanvas1.value)
|
||
Bottom()
|
||
}
|
||
|
||
// 定义要处理的键
|
||
const leads = [
|
||
'LEAD_I',
|
||
'LEAD_II',
|
||
'LEAD_III',
|
||
'LEAD_AVR',
|
||
'LEAD_AVL',
|
||
'LEAD_AVF',
|
||
'LEAD_V1',
|
||
'LEAD_V2',
|
||
'LEAD_V3',
|
||
'LEAD_V4',
|
||
'LEAD_V5',
|
||
'LEAD_V6'
|
||
]
|
||
|
||
const transferleads = ['I', 'II', 'III', 'avR', 'avL', 'avF', 'V1', 'V2', 'V3', 'V4', 'V5', 'V6']
|
||
// 每个心电波形名称数组
|
||
const lead_name = ['I', 'II', 'III', 'aVR', 'aVL', 'aVF']
|
||
|
||
const rlead_name = ['V1', 'V2', 'V3', 'V4', 'V5', 'V6']
|
||
|
||
//将读取到的文件转换成数组
|
||
function handleFileChange() {
|
||
const json = JSON.parse(text.value)
|
||
|
||
leads.forEach((lead, index) => {
|
||
const value = json[lead].trim()
|
||
const commaSeparatedValue = value.replace(/\s+/g, ',')
|
||
const numberArray = commaSeparatedValue.split(',').map(Number)
|
||
beatArray1.value.push(numberArray)
|
||
})
|
||
beatArray2.value = beatArray1.value.slice()
|
||
}
|
||
|
||
// 定义移动画布的函数
|
||
function moveCanvas(direction, count) {
|
||
const xoffset = count === 1 ? 1 : count
|
||
|
||
if (direction === 'left') {
|
||
if (offset !== -20 * 60) offset -= spacing * xoffset
|
||
} else if (direction === 'right') {
|
||
if (offset !== 0) offset += spacing * xoffset
|
||
}
|
||
|
||
// if (direction === 'left') {
|
||
// offset -= spacing
|
||
// } else if (direction === 'right') {
|
||
// offset += spacing
|
||
// }
|
||
topCanvas.value.style.left = offset + 'px'
|
||
topCanvas1.value.style.left = offset + 'px'
|
||
}
|
||
|
||
//清除画布内容
|
||
function eliminate(c_canvas) {
|
||
const ctx = c_canvas.getContext('2d')
|
||
ctx.clearRect(0, 0, c_canvas.width, c_canvas.height)
|
||
}
|
||
function Bottom() {
|
||
drawBottomCanvas()
|
||
drawTopCanvas()
|
||
}
|
||
// 绘制底层画布的内容
|
||
function drawBottomCanvas() {
|
||
if (infoParams.Isgrid === 1) {
|
||
lbackcanvas(leftCanvas.value)
|
||
rbackcanvas(rightCanvas.value)
|
||
drawMultipleLines(bottomCanvas.value, beatArray1.value)
|
||
drawMultipleLines(bottomCanvas1.value, beatArray1.value)
|
||
}
|
||
begin(leftCanvas.value, beatArray1.value)
|
||
beginr(rightCanvas.value, beatArray1.value)
|
||
}
|
||
|
||
// 绘制顶层画布的内容
|
||
function drawTopCanvas() {
|
||
drawMultipleLinesl(topCanvas.value, beatArray1.value)
|
||
drawMultipleLinesr(topCanvas1.value, beatArray1.value)
|
||
}
|
||
//定标电压的画布
|
||
function lbackcanvas(c_canvas) {
|
||
drawBigBG(c_canvas)
|
||
drawSmallGrid(c_canvas)
|
||
drawMediumGrid(c_canvas)
|
||
}
|
||
function rbackcanvas(c_canvas) {
|
||
drawBigBG(c_canvas)
|
||
drawSmallGrid(c_canvas)
|
||
drawMediumGrid(c_canvas)
|
||
}
|
||
|
||
// 绘制函数
|
||
function drawBigBG(c_canvas) {
|
||
const context = c_canvas.getContext('2d')
|
||
context.globalAlpha = 1
|
||
context.fillStyle = 'rgba(0,0,0,0)'
|
||
context.fillRect(0, 0, c_canvas.width + 21, c_canvas.height + 21)
|
||
}
|
||
//画小格子
|
||
function drawSmallGrid(c_canvas) {
|
||
const context = c_canvas.getContext('2d')
|
||
context.globalAlpha = 1
|
||
context.fillStyle = '#ff6b64'
|
||
const dotMarginX = 20 / 5,
|
||
dotMarginY = 20 / 5
|
||
for (let i = dotMarginX; i < c_canvas.width; i += dotMarginX) {
|
||
if (i % 20 !== 0) {
|
||
for (let j = dotMarginY; j < c_canvas.height; j += dotMarginY) {
|
||
if (j % 20 !== 0) {
|
||
context.rect(i, j, 1, 0.5)
|
||
}
|
||
}
|
||
}
|
||
}
|
||
context.fill()
|
||
}
|
||
//中格子
|
||
function drawMediumGrid(c_canvas) {
|
||
const context = c_canvas.getContext('2d')
|
||
context.globalAlpha = 1
|
||
context.strokeStyle = '#ff6b64'
|
||
context.strokeWidth = 1.5
|
||
context.beginPath()
|
||
for (let x = 0.5; x < c_canvas.width; x += 20) {
|
||
context.moveTo(x, 0)
|
||
context.lineTo(x, c_canvas.height)
|
||
}
|
||
for (let y = 0.5; y < c_canvas.height; y += 20) {
|
||
context.moveTo(0, y)
|
||
context.lineTo(c_canvas.width, y)
|
||
}
|
||
context.stroke()
|
||
context.closePath()
|
||
}
|
||
|
||
function begin(c_canvas, beatArray) {
|
||
const ctx = c_canvas.getContext('2d')
|
||
ctx.globalAlpha = 1
|
||
ctx.strokeStyle = '#000000'
|
||
let offset = -50
|
||
const spacing = heightoff.value
|
||
beatArray.forEach((dataArray, index) => {
|
||
if (index <= 6) {
|
||
const x = 0
|
||
const y = offset - dataArray[index - 1] * 0.025
|
||
ctx.beginPath()
|
||
ctx.moveTo(x, y)
|
||
ctx.lineTo(x + 5, y)
|
||
ctx.moveTo(x + 5, y - 40)
|
||
ctx.lineTo(x + 15, y - 40)
|
||
ctx.moveTo(x + 5, y - 40)
|
||
ctx.lineTo(x + 5, y)
|
||
ctx.moveTo(x + 15, y - 40)
|
||
ctx.lineTo(x + 15, y)
|
||
ctx.moveTo(x + 15, y)
|
||
ctx.lineTo(x + 20, y)
|
||
ctx.stroke()
|
||
ctx.closePath()
|
||
if (index > 0 && index < 4) {
|
||
ctx.font = '15px Arial'
|
||
ctx.fillStyle = 'black'
|
||
ctx.fillText(lead_name[index - 1], x + 4, y + 14)
|
||
} else {
|
||
ctx.font = '10px Arial'
|
||
ctx.fillStyle = 'black'
|
||
ctx.fillText(lead_name[index - 1], x + 1, y + 12)
|
||
}
|
||
offset += spacing
|
||
}
|
||
})
|
||
ctx.strokeStyle = '#000000'
|
||
}
|
||
|
||
function beginr(c_canvas, beatArray) {
|
||
const ctx = c_canvas.getContext('2d')
|
||
ctx.globalAlpha = 1
|
||
ctx.strokeStyle = '#000000'
|
||
let offset = -50
|
||
const spacing = heightoff.value
|
||
beatArray.forEach((dataArray, index) => {
|
||
if (index <= 6) {
|
||
const x = 0
|
||
const y = offset - dataArray[index - 1] * 0.025
|
||
ctx.beginPath()
|
||
ctx.moveTo(x, y)
|
||
ctx.lineTo(x + 5, y)
|
||
ctx.moveTo(x + 5, y - 40)
|
||
ctx.lineTo(x + 15, y - 40)
|
||
ctx.moveTo(x + 5, y - 40)
|
||
ctx.lineTo(x + 5, y)
|
||
ctx.moveTo(x + 15, y - 40)
|
||
ctx.lineTo(x + 15, y)
|
||
ctx.moveTo(x + 15, y)
|
||
ctx.lineTo(x + 20, y)
|
||
ctx.stroke()
|
||
ctx.closePath()
|
||
ctx.font = '11px Arial'
|
||
ctx.fillStyle = 'black'
|
||
ctx.fillText(rlead_name[index - 1], x + 2, y + 12)
|
||
offset += spacing
|
||
}
|
||
})
|
||
ctx.strokeStyle = '#000000'
|
||
}
|
||
|
||
//背景
|
||
function drawMultipleLines(c_canvas, beatArrays) {
|
||
const ctx = c_canvas.getContext('2d')
|
||
ctx.clearRect(0, 0, c_canvas.width, c_canvas.height)
|
||
drawBigBG(c_canvas)
|
||
drawSmallGrid(c_canvas)
|
||
drawMediumGrid(c_canvas)
|
||
}
|
||
//左边心电图
|
||
function drawMultipleLinesl(c_canvas, beatArrays) {
|
||
const ctx = c_canvas.getContext('2d')
|
||
ctx.clearRect(0, 0, c_canvas.width, c_canvas.height)
|
||
let offset = 0
|
||
const spacing = heightoff.value
|
||
beatArrays.forEach((dataArray, index) => {
|
||
if (index <= 5) {
|
||
drawLine1(c_canvas, dataArray, offset, index)
|
||
offset += spacing
|
||
}
|
||
})
|
||
}
|
||
//右边心电图
|
||
function drawMultipleLinesr(c_canvas, beatArrays) {
|
||
const ctx = c_canvas.getContext('2d')
|
||
ctx.clearRect(0, 0, c_canvas.width, c_canvas.height)
|
||
let offset = 0
|
||
const spacing = heightoff.value
|
||
beatArrays.forEach((dataArray, index) => {
|
||
if (index > 5) {
|
||
drawLine1(c_canvas, dataArray, offset, index)
|
||
offset += spacing
|
||
}
|
||
})
|
||
}
|
||
//画心电图线
|
||
function drawLine1(c_canvas, beatArray, offset, index) {
|
||
const ctx = c_canvas.getContext('2d')
|
||
ctx.strokeStyle = '#030101'
|
||
ctx.lineWidth = 1
|
||
ctx.beginPath()
|
||
if (index <= 5) {
|
||
if (beatArray.length > 0) {
|
||
const firstX = 0
|
||
const firstY = (heightoff.value-50) - beatArray[0] * infoParams.lineratio + offset
|
||
ctx.moveTo(firstX, firstY)
|
||
for (let i = 0; i < beatArray.length - 1; i++) {
|
||
const x2 = (0 + (i + 1) / 10) * infoParams.suduratio
|
||
const y2 = (heightoff.value-50) - beatArray[i + 1] * infoParams.lineratio + offset
|
||
ctx.lineTo(x2, y2)
|
||
}
|
||
ctx.stroke()
|
||
ctx.closePath()
|
||
}
|
||
}
|
||
if (index > 5) {
|
||
if (beatArray.length > 0) {
|
||
const firstX = 0
|
||
const firstY = (heightoff.value-50) - beatArray[0] * infoParams.lineratio + offset
|
||
ctx.moveTo(firstX, firstY)
|
||
for (let i = 0; i < beatArray.length - 1; i++) {
|
||
const x2 = (0 + (i + 1) / 10) * infoParams.suduratio
|
||
const y2 = (heightoff.value-50) - beatArray[i + 1] * infoParams.lineratio + offset
|
||
ctx.lineTo(x2, y2)
|
||
}
|
||
ctx.stroke()
|
||
ctx.closePath()
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style scoped>
|
||
.container {
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: flex-start;
|
||
width: 100%;
|
||
overflow-x: auto;
|
||
overflow-y: hidden;
|
||
height: 100%;
|
||
max-width: 3920px;
|
||
max-height: 3920px;
|
||
}
|
||
#canvas-container,
|
||
#canvas-container1 {
|
||
overflow-x: hidden;
|
||
overflow-y: hidden;
|
||
position: relative;
|
||
width: 50%;
|
||
height: 77vh;
|
||
margin-right: 0;
|
||
}
|
||
#bottomCanvas,
|
||
#bottomCanvas1 {
|
||
position: absolute;
|
||
/* width: 1140; */
|
||
/* height: 75vh; */
|
||
z-index: 0;
|
||
margin-left: 20px;
|
||
}
|
||
#leftCanvas,
|
||
#rightCanvas {
|
||
position: absolute;
|
||
width: 21;
|
||
/* height: 600px; */
|
||
z-index: 99;
|
||
background-color: rgb(255, 255, 255);
|
||
}
|
||
#topCanvas,
|
||
#topCanvas1 {
|
||
position: absolute;
|
||
width: 1140px;
|
||
/* height: 600px; */
|
||
z-index: 1;
|
||
background: transparent;
|
||
margin-left: 20px;
|
||
}
|
||
canvas {
|
||
position: absolute;
|
||
}
|
||
.myrtip {
|
||
display: flex;
|
||
flex-direction: row-reverse;
|
||
margin-right: 30px;
|
||
}
|
||
.mycheckbox-group {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
}
|
||
.mycheckbox-item {
|
||
margin-left: 5px;
|
||
margin-right: 30px; /* 根据需要调整间距 */
|
||
margin-bottom: 10px; /* 根据需要调整间距 */
|
||
width: 30px;
|
||
}
|
||
/* 添加其他样式 */
|
||
</style>
|