基于C#开发电子病历系统体温曲线图设计
2017-06-23
电子病历(Electronic Medical Record,EMR)系统是一个数字技术、计算机技术、通讯技术、软件工程、图形图像综合技术等多学科的高新科技项目。其完整资料、数据处理、网络传输、诊疗支援、统计分析等均是纸质病历无法比拟的。
体温是电子病历系统中一个重要的数据,比如某病人体温升高可以让临床医生知道该病人有发热的症状。在电子病历系统中,体温单所针对的用户是医院的护士。护士每天记录病人的体温等各项信息,录入到数据库中,系统自动生成电子体温单,并绘制成曲线图。体温曲线图直观地显示了病人的体温等相关数据,这些数据与有关疾病和治疗的知识相结合,可作为进一步诊断及确定治疗方案的基础。
笔者参与开发的电子病历系统根据某大型医院的实际需求,在.NET平台下全程采用C#语言开发实现。本文着重介绍电子病历系统中体温曲线图的设计和实现。
1 电子病历系统主要功能
本系统根据医院的实际需求,最主要的目的是采集病人的数据,使之能为临床医生提供所需要的诊断和决策信息,更进一步的目的是这些信息能够用于临床科研。系统主要功能如图1所示。
2 体温曲线图的设计与实现
2.1 体温表的生成
在电子病历系统中,每个来院就诊的病患在医院就诊期间会产生一个病历号,这是标志病人的确定码,通常在数据库系统中也作为惟一的对应码和关键字。病人人院后,护士对病人进行体温、脉搏、呼吸等各个方面的检测,将这些数据录入到电子病历系统中,系统则自动生成体温单。
在病人的体温单中,需要记录并分析病人的体温变换情况。体温单信息的“体温”、“脉搏”、“呼吸”这三项信息是要每隔4个小时记录1次,分别在4时、8时、12时、16时、20时、24时这几个时间段。而“大便次数”、“小便次数或量”、“摄人量”、“排出量”、“血压”、“体重”等信息是1天记录1次。根据体温单信息,以1天为1个单位,画出1天内病人在各个时间段的“体温”、“脉搏”、“呼吸”的曲线变化情况,以及记录的“大便次数”、“小便次数或量”、“摄入量”、“排出量”、“血压”、“体重”等信息。整个体温图1次只显示7天的情况。在体温图中用坐标以及曲线描述病人体温的连续变化情况,直观地满足了护士对患者的体温、呼吸、脉搏等信息的录入和查询的需要。图2是体温单显示界面。
2.2 体温图的绘制
体温图是根据体温单的数据自动生成的。由于体温图每次只显示病人7天的体温变化情况,所以设计了翻页的功能,对住院时间久的病人通过翻页每次跳过7天,保证病人的体温信息完整的显示。
2.2.1 C#的GDI+绘图
体温图的绘制由.NET基类集组成的GDI+实现,这些基类可用于在屏幕上完成定制绘图,能把合适的指令发送到图形设备的驱动程序上,确保在显示器屏幕上显示正确的输出。
在GDI中,识别输出设备的方式是使用对象设备环境(DC)。该对象存储特定设备的信息,并能把GDI API函数调用转换为要发送给该设备的指令。实现画图的功能要使用到GDI+画图技术。通过重写Form类中的OnPaint(PaintEventArgs e)执行画图操作。
在OnPaint()中,首先从PaintEventArgs中引用Graphics对象,绘制图形。最后调用基类的OnPaint()方法。
在应用程序第一次启动,窗口第一次显示出来时,也调用了OnPaint(),所以不需要在构造函数中复制绘图代码。
由于整个体温图比较大,而显示窗口定为800×600,为了能完整显示体温图文档,需要在文档超出窗口时,通知窗口在右侧出现滚动条。为此,把整个文档区域定为(800,1 886)像素,并在窗体设计器的属性中把AutoScroll属性设置为True。这样,在体温图超过窗口时自动出现滚动条。
2.2.2 绝对坐标到相对坐标的变换
在一般的绘图代码中,由于所绘制的图形区域一般不超过窗口的大小,所以不需要特别的注意。Graphics实例在默认情况下把坐标解释为是相对于窗口的,它并不知道滚动条的情况。当用户滑动滚动条时,Windows没有要求应用程序重新绘制已经显示在屏幕中的内容。Windows只指出屏幕上目前显示的内容可以平滑的移动,以匹配滚动条的位置。对于多出来的文档部分,在应用程序第一次显示时,没有绘制这部分窗口,因为在滚动窗口前,这部分在窗口区域的外部。这表示Windows要求ScrollShapes应用程序绘制这个区域。它将引发Paint事件,把这个区域作为剪切的矩形,在窗口中和原来的图形一起显示出来,这样会出现一个窗口中有多个图形重叠,造成图形的混乱。
解决的方法是把Graphics实例默认的坐标表示为相对坐标,即坐标是相对于窗口的左上角,而不是文档开头的左上角,把绝对坐标转换为相对坐标。这里用图3说明这一转换。
实线矩形标记了屏幕区域的边框和整个文档的边框。虚线矩形标记了试图要绘制的矩形和椭圆。P标记要绘制的某个随意点。在调用绘图方法时,提供Graphics实例和从A点到P点的矢量,整个矢量表示为一个Ponit实例。而实际上需要的是从点B到点P的矢量。问题是,这里只知道从A点到P点的矢量,这是P相对于文档左上角的坐标,而要在文档的P点绘图。另外还知道从A点到B点的矢量,这是滚动的距离,它储存在Form类的一个属性AutoScrollPosition中。要知道从B点到P点的矢量只需要进行矢量相减即可。Graphics类的TranslateTransform方法可以进行这些矢量的计算。这里给它传送水平和垂直坐标,表示窗口驱谴、与的左上角相对于文档的左上角的矢量(AutoScrollPosition属性,它是图中从A到B的矢量),然后Graphics设备考虑窗口区域相对于文档区域的位置,处理这些坐标。只要在绘图代码中加入以下语句:g.TranslateTransform(this.AutoScrollPositiort.X,this.AutoScrollPosition.Y);即可解决坐标转换的问题。
2.2.3 体温图的绘制技术
体温图的绘制根据体温单中病人的相关信息,利用才C#的GDI+可以绘制出相应的体温曲线图。在程序中首先进行绝对坐标和相对坐标的变换,然后用Pen类定义画笔,用Brush类定义画刷颜色,对于需要填充的地方用画刷进行填充,再调用Graphics类的DrawLine方法画出所需的线条。在DrawLine方法中,需要提供画笔类型,线段起点和终点坐标等参数。
体温图初始化之后,根据从体温表传递的病人编号作为体温图中的全局变量,对数据库进行查询,并把查询结果转换为坐标,传递给画图方法DrawLine和FillEllipse,画出图形。图4是一张体温图显示界面。
2.2.4 体温图中翻页的实现
由于体温图每次只显示病人1周的体温变换信息,要显示1周之前的体温信息,可以使用翻页功能。实现翻页功能主要利用在读取数据时使用到的Read()方法的特性。通过Read()方法在读取数据的同时把当前的指针向下移动1位。最初它位于数据集的第一行之前,因此第一次调用Read()将把指针置于第一行上,使它成为当前行。随着每次调用Read()导致指针向下移动,按照从上至下的次序获取数据集行。代码如下:
其中变量n为全局变量,由翻页按钮对其进行赋值。以当前的变量n减1乘7为所需跳过的间隔数,以日期为单位,对数据集中的日期进行筛选,选出这一周的日期储存到数组array中。
3 结 语
电子病历是医院信息化发展的必然趋势。根据HL7的标准化要求,当前国内电子病历的研究还很不完善,要制定出比较完善的适应国内医院使用的电子病历原型系统还需要更深入的研究。本文探讨利用C#绘制电子病历系统体温图的技术,试图对完善电子病历系统做有益的尝试。电子病历系统相关的研究内容将会不断发展和深入,而电子病历的技术构架和软件流程也将会越来越成熟。