vue 简易心电图组件

这是一个适用于 vue2 的利用 canvas 绘制的简易心电图组件

 

代码简陋,能实时响应数据变化(非深度监听,需要更新对象)

xy轴提示文字可以隐藏 为了绘制完整性,绘制时会忽略页面 %50 部分的宽 

左侧文字宽 50px  底部文字高 20 px
请在设置组件宽高时尽量将宽度设置为50的倍数,将高度设置为50的倍数+20,非此规则的宽高将不会用来绘制图

使用方式:

<ecg 
    :height="240"
    :width="750"
    :tip="true" //是否显示xy轴文字
    :maxV="500" //最大电压
    :ecgData="[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -240, -230]"
></ecg>



页面 ecg.vue
 

<template id="ecg">
	<div
		ref="ecgContent"
		class="ecgContent"
		id="ecgContent"
		:style="{ width: width + 2 + 'px', height: height + 'px' }"
	>
		<canvas ref="ecgCanvas" id="ecgCanvas" v-if="show"></canvas>
	</div>
</template>

<script>
export default {
	data() {
		return {
			ecgList:[],
			show: true,
			canvas: null,
		}
	},
	props: {
		tip: {
			type: Boolean,
			default: () => {
				return true
			},
		},
		width: {
			type: Number,
			default: 240,
		},
		height: {
			type: Number,
			default: 750,
		},
		ecgData: {
			type: Array,
			default: () => {
				return []
			},
		},
    maxV:{
      type:Number,
      default:500
    },
	},
	async mounted() {
		this.ecgList = this.ecgData
		this.init()
	},
	watch: {
		ecgData(val) {
			this.ecgList = val
			if (this.canvas) {
				this.$nextTick(()=>{
					this.draw()
				})
			}
		},
	},
	methods: {
		init() {
			if (!this.$refs.ecgCanvas) {
				setTimeout(() => {
					this.init()
				}, 50)
				return
			}

			let canvas = (this.canvas = this.$refs.ecgCanvas)
			canvas.width = Math.floor(this.width / 50) * 50 + 2
			canvas.height = this.height
			this.$nextTick(() => {
				setTimeout(() => {
					console.log(this.width, this.height)
					this.draw()
				}, 100)
			})
		},
		draw() {
			var canvas = this.canvas
			if (canvas.getContext) {
				var ctx = canvas.getContext('2d')
				var offsetx = 50
				var offsety = 1
				var width = this.width
				var height = this.height
				var gridWidth = Math.floor(width / 50) * 50
				var gridHeight = Math.floor((height - 20) / 50) * 50

				if (!this.tip) {
					offsetx = 1
					gridHeight = Math.floor(height / 50) * 50
				}

				ctx.fillStyle = 'rgba(255,255,255,1)'
				ctx.fillRect(offsetx, offsety, width, height)

				var d = 10

				for (var i = 0; i <= gridWidth / d; i++) {
					if (i % 5 == 0) {
						ctx.strokeStyle = 'rgba(63, 169, 252,.6)'
						ctx.lineWidth = 2
					} else {
						ctx.strokeStyle = 'rgba(63, 169, 252,.3)'
						ctx.lineWidth = 1
					}
					ctx.beginPath()
					ctx.moveTo(i * d + offsetx, offsety)
					ctx.lineTo(i * d + offsetx, gridHeight + offsety)
					ctx.stroke()
				}

				for (var j = 0; j <= gridHeight / d; j++) {
					if (j % 5 == 0) {
						ctx.strokeStyle = 'rgba(63, 169, 252,.6)'
						ctx.lineWidth = 2
					} else {
						ctx.strokeStyle = 'rgba(63, 169, 252,.3)'
						ctx.lineWidth = 1
					}
					ctx.beginPath()
					ctx.moveTo(offsetx, j * d + offsety)
					ctx.lineTo(gridWidth + offsetx, j * d + offsety)
					ctx.stroke()
				}

				if (this.tip) {
					ctx.font = '15px Arial'
					ctx.fillStyle = 'rgb(0,0,0)'
					ctx.fillText('time/ms', offsetx + width / 2 - 50, gridHeight + 20)

					ctx.fillText('1.0mv', 0, 11)
					ctx.fillText('0', 20, gridHeight / 2 + 5)
					ctx.fillText('-1.0mv', 0, gridHeight)
				}

				this.drawLine(gridHeight / 2)
			}
		},
		drawLine(zero) {
			var context = this.canvas.getContext('2d')
			//线条颜色为绿色
			context.strokeStyle = '#f03e3e'
			//线条粗细为2
			context.strokeWidth = 2
			// 起始位置
			let x = 50
      if(!this.tip){
        x = 1
      }
			context.moveTo(x, Math.floor(Math.floor(this.height / 15) / 2) * 15)
			context.beginPath()
			/**for循环 */
			let gap = (this.width - 2) / this.ecgList.length
      console.log(gap)
      if(gap > 1){
        gap = 1
      }
			for (let i = 0; i < this.ecgList.length; i++) {
				let after = this.getPoiont(this.ecgList[i], zero)
				context.lineTo(x, after)
				x += gap
			}
			context.stroke()
			context.closePath()
		},
		getPoiont(value, zero) {
			let point = zero
			let max = this.maxV
			let bl = point / max
			if (value > 0) {
				point = zero - value * bl
			} else if (value < 0) {
				point = zero + -value * bl
			}
			return point
		},
	},
}
</script>

<style>
.ecgContent {
	width: 100%;
	height: 100%;
}
#ecgCanvas {
	width: 100%;
	height: 100%;
}
</style>


参考于大佬文章:
csdn作者:涛哥带你学编程  文章:canvas绘制心电图(js读取csv心电数据文件)- 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值