#打卡不停更#harmonyos-基于arkui(ets)实现心电图组件(代码片段)

author author     2022-12-05     199

关键词:

作者:杨尚晓

前言

随着大家生活水平的提升,越来越多的人注重自身身心健康,养生成了目前比较热门的活动。心电图是检测心脏活动状态的直观表现,可以通过心电图来观察人提的健康状况。 响应鸿蒙万物互联的口号,肯定少不了智能设备和心电检测设备的互联。所以本文实现了简单的心电图功能UI展示。

效果图

组件API

ygEcg

属性名 类型 默认值 描述
ecgData EcgDataType - 配置心电图的信息

接口 EcgDataType

参数名 参数类型 必填 默认值 参数描述
data Array<number> - 心电数据源
timeStep number 40 每一小格代表时间(毫秒),x轴方向
mvStep number 0.1 每小格表示电压(毫伏/mv),y轴方向
waveLineColor string - 波线颜色
gridColor Array<string> - 网格颜色,第一个为小网格,第二个为大网格
maxTime number - 图标显示最大时间区域(毫秒)
width number - 画布宽度
height number - 画布高度
backgroundColor string - 画布背景色

组件调用

// import 引入接口和组件
import ygEcg,EcgDataType from ./../common/compontents/ygEcg

@Entry
@Component
struct Index 
    @State ecgData:EcgDataType = 
        data: [
        0, 0, 0, 0.1, 0, 0, 0, -0.2, 1.5, -0.4, 0, 0, 0, 0.1, 0.2, 0.1, 0, 0, 0,
        0, 0, 0, 0.1, 0, 0, 0, -0.2, 1.0, -0.4, 0, 0, 0, 0.1, 0.2, 0.1, 0, 0, 0,
        0, 0, 0, 0.1, 0, 0, 0, -0.2, 1.0, -0.4, 0, 0.1, 0, 0.1, 0.2, 0.1, 0, 0, 0,
        0, 0, 0, 0.1, 0, 0, 0, -0.2, 2.0, -0.3, 0, 0, 0, 0.1, 0.2, 0.1, 0, 0, 0,
        0, 0, 0, 0.1, 0, 0, 0, -0.2, 1.0, -0.4, 0, 0, -0.1, 0.1, 0.2, 0.4, 0, 0, 0,
        0, 0, 0, 0.1, 0, 0, 0, -0.2, 1.0, -0.4, 0, 0, 0, 0.1, 0.2, 0.2, 0, 0, 0,
        0, 0, 0, 0.1, 0, 0, 0, -0.2, 1.0, -0.4, 0, 0.1, 0, 0.1, 0.2, 0.1, 0, 0, 0,
        0, 0, 0, 0.1, 0, 0, 0, -0.2, 1.0, -0.4, 0, 0, 0, 0.1, 0.2, 0.1, 0, 0, 0,
        0, 0, 0, 0.1, 0, 0, 0, -0.2, 1.0, -0.4, 0, 0, 0, 0.1, 0.2, 0.1, 0, 0, 0,
        ],
        timeStep: 40, // 每一小格表示40毫秒,x轴方向
        mvStep: 0.1, // 每小格表示0.1mv,y轴方向
        waveLineColor: #181818, // 波线颜色
        gridColor: [#ffa5a5,#dd0000], // 网格颜色,第一个为小网格,第二个为大网格
        maxTime: 6000,
        width: 700,
        height: 300,
        backgroundColor: #fff
    
    build() 
        Row()
          ygEcg(ecgData: $ecgData)
        
        .justifyContent(FlexAlign.Center)
        .alignItems(VerticalAlign.Center)
        .width(100%)
        .height(100%)
        //    .backgroundColor(#151515)
    

实现前的准备

在写这个demo之前,以为心电图应该就是现在简单的上下波动的折线图 以为是这样的(图片来源于网络) 实际上医学上心电图是这样的(图片来源于网络) 最后上网补了一下相关知识,大概了解到的对应的波形和走纸速度的关系(图片来源于网络)

因为没有见过真实的数据结构,所以参考了上图的波形和走纸速度,自己模拟了一组数据

实现原理

通过使用canvas组件,绘制一个类似医学上的心电图纸网格,然后通过心电源数据,绘制对应的折线形成心电波形

实现过程

1. 创建canvas画布

@Component
struct ygEcg 
  private settings: RenderingContextSettings = new RenderingContextSettings(true);
  private ctx: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings)
  @Link ecgData: EcgDataType;
  build() 
    Canvas(this.ctx)
      .onReady(()=>
      )
      .width(this.ecgData.width)
      .height(this.ecgData.height)
      .backgroundColor(this.ecgData.backgroundColor)
  

2. 绘制小网格

因为通上面的心电波形图解得知,默认一个小网格的走纸速度是0.04秒,也就是40毫秒,通过传入的数据timeStep字段控制 那么要绘制多少个小格呢?通过画布宽度,和maxTime字段(最大的显示时间,上面代码案例是6000毫秒)可以计算得知,将要绘制 6000/40=150小格

  // 组件生命周期
  aboutToAppear() 
    // 计算每1小格需要绘制的宽度
    this.littleGridSize = Math.floor(this.ecgData.width / (this.ecgData.maxTime / this.ecgData.timeStep))
    // 计算每1大格需要绘制的宽度(每5小格是1大格)
    this.LargeGridSize = this.littleGridSize * 5
  
//   绘制小格
  drawLittleGrid = ():void => 
    let c = this.ctx;
    let width:w, height: h = this.ecgData;
    c.strokeStyle = this.ecgData.gridColor[0];
    c.lineWidth = 0.5;
    c.beginPath();
    for(let x = 0; x <= w; x += this.littleGridSize)
      c.moveTo(x, 0)
      c.lineTo(x, h)
      c.stroke()
    
    for(let y = 0; y <= h; y += this.littleGridSize)
      c.moveTo(0, y)
      c.lineTo(w, y)
      c.stroke()
    
    c.closePath();
  

3. 绘制大网格

每1大格等于5小格

//  绘制大格
  drawLargeGrid = ():void => 
    let c = this.ctx;
    let width:w, height: h = this.ecgData;
    let lg = this.LargeGridSize;
    c.strokeStyle = this.ecgData.gridColor[1];
    c.lineWidth = 0.5;
    c.beginPath();
    for(let x = 0; x <= w; x += lg)
      c.moveTo(x, 0);
      c.lineTo(x, h);
      c.stroke();
    
    for(let y = 0; y <= h; y += lg)
      c.moveTo(0, y);
      c.lineTo(w, y);
      c.stroke();
    
    c.closePath();
  

最后绘制的结果如图

4. 绘制心电波形

获取画布高度的一半位置,作为心电波形的基线,在基线的基础上,通过心电数据源,将每个数据在基线上通过对数据的偏于来绘制点线,最后形成一个折线状态的心电波形线

// 数据视图更新
  update = (data?: Array<number>):void => 
    let c = this.ctx;
//    c.clearRect(0, 0, this.ecgData.width, this.ecgData.height)
    c.beginPath();
    c.strokeStyle = this.ecgData.waveLineColor;
    c.lineWidth = 1.2;
    c.lineJoin = round
    c.lineCap = round
    let point = data || this.ecgData.data;
    if(point.length === 0) return;

    //开始遍历输出数据
    c.moveTo(0, Math.floor(this.ecgData.height / 2))
    for (let i = 0; i < point.length; i++) 
      let x = i * this.littleGridSize;
      let y = Math.floor(this.ecgData.height / 2) + point[i] * this.LargeGridSize * -1
      c.lineTo(x, y);
      c.stroke();
    
    c.closePath();

  

刷新预览器看看效果

5. 最后一步实现心跳的动画效果

这里的动画刷新时间是根据配置的心电图步长来做定时器的时间,默认是40毫秒,也就是每一小格走纸的时间。这样就可以保持跟实际时间对应,不会出现心跳快慢的问题。 当然,这里还是有写误差的,因为代码执行的过程也是消耗时间的,会比实际时间多一丢丢

//  获取心律数据
  getEcgData = ():void => 
    let points = this.ecgData.data;
    //最后传递出去的数据
    let pointsLast = [];
    //当前取到了第几个数据了
    let currInedx = 0;
    let timer = null;
    clearInterval(timer)
    timer = setInterval( ()=> 
      if(currInedx < points.length)
        currInedx ++;
        pointsLast = points.slice(0,currInedx)
        this.update(pointsLast)
       else 
        clearInterval(timer)
      
    ,this.ecgData.timeStep)
  

最后再来看一下心电图的动画效果

代码地址

https://gitee.com/yango520/yg-ecg2

总结

绘制这个心电图没有用到重绘机制,动画效果是每次绘制的时候覆盖在原有的波形线上的,但是这样会比重绘整个画布性能更好一些。 通过实现这个demo之后,对心电图上的信息有了全新的了解,我觉得大家都可以去学会看心电图来分析心脏状况,自己理解了总比别人告知更有说服力。

避坑小技巧

  1. 当代码大变更的时候(一般复制出来单独做一个文件的时候),需要在build选项卡里清理项目,不然也不报错,也不刷新,但是样式就是错乱。
  2. 预览器开久了之后,当一段时间不动了,再次刷新开启都一直卡着开启中进不去,需要关闭IDE重新打开才可以用。

更多原创内容请关注:中软国际 HarmonyOS 技术团队

入门到精通、技巧到案例,系统化分享HarmonyOS开发技术,欢迎投稿和订阅,让我们一起携手前行共建鸿蒙生态。

想了解更多关于开源的内容,请访问:​

​51CTO 开源基础软件社区​

​[​https://ost.51cto.com/#bkwz​

#打卡不停更#harmonyos-基于arkui(ets)实现心电图组件(代码片段)

作者:杨尚晓前言随着大家生活水平的提升,越来越多的人注重自身身心健康,养生成了目前比较热门的活动。心电图是检测心脏活动状态的直观表现,可以通过心电图来观察人提的健康状况。响应鸿蒙万物互联的口号,肯定少... 查看详情

#打卡不停更#openharmony-arkui(ts)声明式开发之列表拖动排列(代码片段)

...基于TS扩展的声明式开发范式,因为OpenHarmony的API相对于HarmonyOS的API,功能上比较完善和成熟的,有些新的技术也早早接触到,所以本项目直接使用OpenHarmonySDK开发。工具版本:DevEcoStudio3.0ReleaseSDK版本: 查看详情

基于openharmony/harmonyos操作系统的arkui框架——harmony原生开发

一.基于OpenHarmony/HarmonyOS操作系统的ArkUI框架——Harmony原生开发开发需要的IDE:1.1什么是ArkUI框架?ArkUI是一套构建分布式应用界面的声明式UI开发框架。它使用极简的UI信息语法、丰富的UI组件、以及实时界面预览工具,帮助您提... 查看详情

harmonyos-基于arkui(js)实现图片旋转验证(代码片段)

...习其他人的slider滑块组件衍生出的小组件,本文主要结合HarmonyOS官网上的相关组件以及通用API,来实现一个图片的旋转验证--需拖动滑块将图片旋转还原为正确,方可验证通过。效果演示实现原理触发条件基于HarmonyOS通用事件touc... 查看详情

harmonyos-基于arkui(js)实现彩带飘动特效(代码片段)

...购物是经常看到一个彩带飘动的特效,又恰逢最近在学习HarmonyOS开发的知识,便想着自己能否用HarmonyOS相关的知识也做一个类似的东西,于是就自己动手尝试了一下。效果展示实现原理彩带飘动特效,主要是使用canvas来实现的,... 查看详情

harmonyos-基于arkui(ets)实现猫头鹰动画(代码片段)

作者:范颖前言因为工作原因,后面我可能会接触到基于TS扩展的声明是开发范式,因此我需要提前学习关于ets的内容。在学习了一段时间之后,我决定用ets来画一只猫头鹰,看看ets跟我之前掌握的知识有何不同,在什么地方需... 查看详情

#夏日挑战赛#harmonyos-基于arkui(js)实现打地鼠游戏(代码片段)

...:尹宝荣本文正在参加星光计划3.0–夏日挑战赛前言初学HarmonyOSArkUI(JS),对于FA的开发还是不太熟悉,单纯看文档,不使用起来的话,始终掌握不了,代码还是要多敲多思考才能进步。所以周末突发奇想利用HarmonyOS写了一个简单的... 查看详情

harmonyos-基于arkui(js)实现信件弹出效果(代码片段)

作者:罗晓纯前言自从大家使用QQ、微信、邮件等网络平台交流以后,大家对纸这种介质和书信这种通讯方式可能都比较陌生了。可别觉得书信是一个过时的东西,它可是80后的情怀,90后的回忆,00后的新宠,是经典的代名词。... 查看详情

harmonyos-基于arkui(js)实现黑白翻棋小游戏(代码片段)

作者:苏亚雯前言本人经过一段HarmonyOS的学习,运用所学的知识,制作了一个黑白翻棋的游戏,来检验自己的学习成果。本文详细讲述了黑白翻棋的编写思路,内含详细解释,有兴趣的小伙伴可以自己动手来制作一个属于自己的... 查看详情

#打卡不停更#ffh浅析ability框架中stage模型与fa模型的差异(代码片段)

...能力的抽象,也是应用程序的基本组成单元。OpenHarmony与HarmonyOS的应用程序APP由一个或多个Hap包组成,每个Hap可以包含一个或多个Ability。Ability框架模型具有两种形态,FA模型以及Stage模型:FA模型:OpenHarmonyAPI8 查看详情

基于stm32的串口收发讲解(hal库)#打卡不停更#(代码片段)

(基于STM32的串口收发程序(HAL库))介绍串口(UART通用异步收发器,TTL)通讯是一种设备间的串行全双工通讯方式。由于UART是异步传输,没有传输同步时钟,为了保证数据的正确性,UART采用16倍数据波特率的时钟进行采样。因为... 查看详情

openharmony/harmonyos的arkui的类web范式开发详解(代码片段)

一.OpenHarmony/HarmonyOS的ArkUI的类Web范式开发1.1类Web范式~三件套开发基于JS扩展的类****Web开发范****式的方舟开发框架包括应用层(Application)、前端框架层(Framework)、引擎层(Engine)、平台适配层(PortingLayer)JSUI框架采用类HTML和... 查看详情

arkui新能力,助力应用开发更便捷

...xff0c;并能在多种设备上实现生动而流畅的用户体验。随着HarmonyOS3.1版本的发布,ArkUI也新增许多能力,助力应用开发更便携。ArkUI框架新增能力概览ArkUI 查看详情

openharmony-基于arkui(ts)开发颜色选择器(代码片段)

...基于TS扩展的声明式开发范式,因为OpenHarmony的API相对于HarmonyOS的API,功能上比较完善和成熟的,有些新的技术也早早接触到,所以本项目直接使用OpenHarmonySDK开发。工具版本:DevEcoStudio3.0Beta4SDK版本:3. 查看详情

#打卡不停更#ffhopenharmony学生挑战赛分享-少儿语言教育app(代码片段)

Openharmony学生挑战赛经验分享前言本次参赛的项目是基于openHarmony开发的北向应用-少儿语言文化教育APP。从项目成立到初版成型再到参加比赛,这一路上遇到了不少困难,我也从团队协作、产品迭代、技术等方面学到了很多宝贵... 查看详情

#打卡不停更#智能喂食器(代码片段)

一、介绍​随着人们生活方式的不断改变,宠物猫在许多家庭中占有重要的地位,其凭借独立的个性和易于打理的饲养方式,成为当下上班族喜欢的宠物之一,人们更是把宠物猫和狗作为家庭的重要成员。有铲屎官表示,每月在... 查看详情

#打卡不停更#-openharmony/docs开发入门(代码片段)

作者:朱子道杨成前言不管是作为软件开发的爱好者还是已经从事软件开发这个行业的从业者,对于接触一种全新的系统OpenHarmony。学习OpenHarmony,需要清楚OpenHarmony这个系统是什么,能干什么,今日分享从设备开发和应用开发两... 查看详情

#打卡不停更#三方库移植之napi开发[2]c/c++与js的数据类型转换(代码片段)

在《三方库移植之NAPI开发[1]—HelloOpenHarmonyNAPI》通过一个HelloOpenHarmonyNAPI样例讲述了NPAI接口开发基础知识。本文在其基础上修改hellonapi.cpp文件,介绍JS类型和C/C++数据类型之间的转换。开发基于最新的OpenHarmony3.2Beta3版本及其对应... 查看详情