大概说说这个事情的前因后果吧。
去年下半年,我有机会参加了一个大型项目,在里面参与了前端可视化组建的开发,用的library是D3.js [2]。虽然3个月后我就结束了在这个项目里的工作,但后面断断续续也用D3做了一些别的实现。
而从几年前开始,我一直在做和healthcare相关的项目,主要就是做医疗数据的信息化,从而优化医疗领域的信息管理、决策支持。从项目的角度出发,我们的着眼点一般都是某个具体的问题,比如如何优化病人诊疗的流程。但从宏观上出发,如果能了解某个地区乃至全国的医疗服务情况是怎么样的,也是 非常有意义的 。
结合这两者,我就想做一件事情,将一些宏观的医疗服务数据通过可视化技术,更直观地表达出来。
对于做这个事情,个人认为也有一些原则要遵守。首先,最基本的,医疗数据的来源要公开、权威。其次,最重要的,这样的可视化要体现医疗服务的特点,使得其在医疗领域能体现价值。当然,这不是一蹴而就的,而需要不断地在探索和实践中摸索。实践本身也是一个学习的过程。除了D3.js官网的API文档,主要的参考书就是Nick Qi Zhu的《D3.js数据可视化实战手册》[3]。由于本人较懒,后面很多实践也是在Nick的源码基础上直接修改所得。
本着公开、权威的原则,找到了国家卫生和计划生育委员会统计信息中心[1]的统计数据。由于在这个阶段我的目标是验证医疗数据可视化的一个实现的流程,因此并没有花太多时间在数据的抓取上。通过简单的调研,发现其中全国医疗服务情况的数据还比较全面。而由于精力所限,最终选择了以下几类医疗卫生机构医疗服务量中的诊疗人次数,输出的是JSON格式文档。
{
"医疗卫生机构合计": [
{
"date": "2013-05",
"value": 60005.2
},{
"date": "2013-06",
"value": 58861.9
},{
"date": "2013-07",
"value": 60264.2
},{
"date": "2013-08",
"value": 59519.3
},...
], ...
}
通过对数据的解读并结合之前的原则,我一开始的想法是想用D3图表表现全国不同医疗机构月均诊疗人次数随着时间的变化。也就是说,图表的横轴是时间,纵轴是诊疗人次数,而不同的医疗机构的数据能够出现在同一个图表中以便做对比。因此,我自然而然将线图(linechart)作为了第一选择。
对于基本线图的实现,《D3.js数据可视化实战手册》中有很好的例子,也提供了源码,因此在整个coding过程中,比较多的时间花在了数据的处理上。本人使用的D3版本是3.5.5。源码如下。
全国医疗卫生机构医疗服务量
分析一下几个技术点。
D3提供了d3.json,但很不幸地,此API只能加载list式的JSON(例如[1,2, 3])而不能加载key-value式的(例如{“id”:1})。而我之前构造的数据是以不同机构的名字作为key,其下面的数据列表作为value。因此我选择了用d3.text加载JSON文件成String,再通过JSON.parse将String变换成JSON Object。
接下来,考虑到每条线对应的是list式的数据,因此还需要对原始JSONObject做一些变换,比如将每个value中的list放到list变量data中,并将原来以字符串形式存在的date通过d3.time.format变换成Date Object。
要生成x轴和y轴,需要设置其合理的domain。这儿就要计算数据的最大最小值。对x轴而言,对应的是数据中的日期。而对不同的医疗机构而言,这儿我们假设其数据的日期范围是一样的,因此只要对一个机构的数据进行计算即可。用到的就是d3.min和d3.max。并且由于每条数据是一个JSON Object,设置d3.min和d3.max的accessor为一个返回date的function。对于y轴而言,需要计算所有机构的数据的最大最小值,因此使用了嵌套的d3.min和d3.max。
从呈现的结果来看,达到了初步的预期:每种机构的日均诊疗人次数各有大小;总体呈缓慢上升趋势;过年期间会小降;等等。
但总体而言,这个可视化呈现还有很多待改进的地方。
1. 需要显示图例,说明每条曲线对应的机构
2. x轴最好能显示每个月的中文名字,中间区域内的网格也是每个月一格。
3. 由于其中的机构种类有包含关系,是否对其改用堆积区图 (stackedarea chart) 比较好?
4. 从美观考虑,线的出现最好有动画效果。
后面的系列会陆续探讨这几点。
1. 国家卫生和计划生育委员会统计信息中心.http://www.moh.gov.cn/mohwsbwstjxxzx/index.shtml
2. D3.jsAPI Reference. https://github.com/mbostock/d3/wiki/API-Reference
3. Nick Qi Zhu. D3.js数据可视化实战手册. http://book.douban.com/subject/26256865/