HTML5数据可视化第一弹:彩虹爆炸图

By | 05月19日
Advertisement

前言

25年过去了,Brooks博士著名的“没有银弹”的论断依旧没有被打破。HTML5也是一样。但这并不妨碍HTML5是一个越来越有威力的“炸蛋”:发展迅速、势不可挡。随着HTML5技术的普及,用HTML5做可视化呈现的项目越来越多了。HTML5的优势明显:网页上直接运行无需插件、手机平板方便兼容、代码开发和维护相对容易,等等。一大波一大波的做Java、.NET甚至C++桌面的程序老手们都纷纷开始研究javascript了,而初出茅庐的新一代程序猿更是义无反顾的直奔HTML5这个技术大热点而来。

HTML5涵盖的技术点很多,甚至延伸到了前端、后端、通讯等各个层面。前端的canvas绘图这块无疑是它的核心内容。Canvas的API虽然不是很复杂很强大,但是做一般的2d绘图基本都够用了。基于这些API,一大堆的2d绘图组件纷纷出炉。Echarts、d3.js都是很不错的项目。Echarts主要是chart组件,而d3相对杂一些,很多呈现方式很有创意,值得研究。

概述

研究d3的起因是最近有一个项目,用户截了一张效果图让我们用HTML5做一下:

HTML5数据可视化第一弹:彩虹爆炸图

看着很眼熟,搜了一下,感觉就是d3例子中的sunburst效果,程序在这里:

http://bl.ocks.org/mbostock/4063423

看上去似乎也不难,就是一圈一圈的饼图,把树状结构数据按占比一层一层绘制上去就行了。所以引起了自己动手做一个的兴趣。“sunburst”英文里应该是“云开日出”的意思,类似强烈的光芒从云层背后透射出来,不知为何中文里大多把它翻译成“日落”。比如这把Fender Telecaster吉他型号是Brown Sunburst款,就会被大家翻译成“日落色”。

HTML5数据可视化第一弹:彩虹爆炸图

关于日出和日落更喜欢哪一个的问题,网上还真有这样的调查。有意思的是,选择喜欢日落的远多于选择日出的。日出代表希望,日落代表成熟,都是一种美,哪个更美要看你个人的心境,因为它的美丽是由心生。为了不在这个问题上站错对,我们还是给他重新起一个更加响亮霸气的中文名字:“彩虹爆炸图”,怎么样?

仔细研究一下彩虹爆炸图的结构,无非就是一个树形结构,并采用发射状的布局。根节点在中间(也可以认为没有唯一的根,而是一堆根节点围绕在第一圈),一次向外发散排列。每一个节点有名称、数值。节点可以按照自身数值在扇区所占比例进行绘制,这样就不用管节点具体数值有多大多小了。

这种图最先是由布朗大学教授John T. Stasko设计。

http://www.cc.gatech.edu/~john.stasko/

经过一天的折腾,终于做出了一个还算过得去的“彩虹爆炸图”。先上个图看看:

HTML5数据可视化第一弹:彩虹爆炸图

主要功能包括了:

  1. 可以通过json来定义数据和样式(类似百度的echarts那样);
  2. 颜色可以固定,也可以自动彩虹色;
  3. 自动计算数值及角度占比;
  4. 动态显示导航路径;
  5. 鼠标动态高亮显示路径;
  6. 动画飞入、展开导航路径;
  7. 文字显示及角度控制;
  8. 全矢量,可鼠标缩放、平移,不失真;

下面重点码一下折腾过程中的几个重点:

一、定义节点对象

首先定义每一个小扇片节点。每个扇片可以用一段饼图来绘制。为了简单方便,这里用了最简单高效偷懒的方法:用一个半径很粗的线画一段角度的arc,即可。如下图:

HTML5数据可视化第一弹:彩虹爆炸图

另外还有文字等内容。所以定义它的json结构大概如下:

var item = {name: '名称', color: 'red', angle: '45', …};

此外,下一圈的数据,可直接定义为这个节点的“孩子节点”,直接在item中定义一个data的子节点数据:

var item = {name: '名称', color: 'red', angle: '45', data:[

{name:’孩子一’, color:’green’,…},

{name:’孩子二’, color:’yellow’,…},

]};

这样就可以组成一个树状结构。接下来要在canvas上绘制图形了。为了方便,这里直接使用了矢量图进行定义:

twaver.Util.registerImage('node', {

v: [{

shape: 'circle',

r: ...

lineColor: function(data,view){return data.getClient("lineColor");},

lineWidth: ...

startAngle: ...

endAngle: ...

},{

shape: 'text',

textBaseline: 'middle',

textAlign: ...

text: ...

x: ...

y: ...

font: ...

fill: ...

rotate: ...

visible: ...

shadow: ...

}],

});

矢量图中定义了2个图形元素:一个arc弧线、一个文字对象,分别用于画node和绘制其文字。颜色、字体、是否可见、阴影、对齐、位置、线宽、角度…等等均在上面的定义中用一个function动态获取。例如,这个节点的半径,通过下面的方法,就可以在图形的lineColor属性中保存并驱动,需要修改,直接修改lineColor这个client属性即可,而不用去修改绘图参数,非常方便:

r:function(data,view){return data.getClient("lineColor");}

这里有一个比较啰嗦的地方是:每个扇片的角度需要根据每个item定义的原始值进行计算角度占比。而且,对于太小的扇片,可以给一定的最小值(例如1度),保证能视觉上看到它。否则,显示10000和1两个数值,由于对比过大,可能就杯具了,因为1连1度都占不到,显示效果会非常差。还有,每个扇片之间应该尽量留有一定的空隙。如果连续绘制,就会连成一片,没有“分片”感。这些可以在代码中进行简单控制。

二、文字控制

文字控制也比较啰嗦。首先是对齐方式。最简单的方式当然是让文字在所在扇片处,直接居中、旋转。这样文字会在径向的中间位置,如下图:

HTML5数据可视化第一弹:彩虹爆炸图

但这样显示感觉并不是很完美。对于中文来说,如果能统一靠近圆心方向的位置对齐,会更好看一些。这样,即使文字过长,也会向外延伸,不会和里面的重叠。如下图:

HTML5数据可视化第一弹:彩虹爆炸图

还有,当文字在左半圆时,如果不做特殊处理,文字旋转会导致文字大头朝下,阅读起来有把脖子歪断的风险。所以应该动态判断,如果文字在左侧,应该文字再增加旋转180度。同时左侧的文字对齐也要特殊考虑,应该变成右对齐,才能保持径向的整齐一致。

HTML5数据可视化第一弹:彩虹爆炸图

文字还有一个细节就是颜色和阴影的问题。不使用阴影,单纯的使用颜色(例如白色),则在一些方向上的节点的文字会看不清楚,因为我们做的是彩虹爆炸图,各个方向颜色都不一样,而且还会随着圈数增加而变淡颜色,所以几乎不可能用一个固定的颜色(例如白色或黑色)能保证文字在所有地方都能和node颜色搭配并看清楚。所以思来想去还是使用了阴影效果。

HTML5数据可视化第一弹:彩虹爆炸图

联想了一下我们看美剧时候的字幕,似乎也是同样的问题。视频字幕要显示在千变万化的视频场景里面,视频场景的颜色完全随机出现无从知晓,要想让字幕看清楚,必然也会想一些办法解决。我们仔细观察一下视频字幕:

HTML5数据可视化第一弹:彩虹爆炸图

仔细观察,字幕是白色文字加了一圈黑色外框,这样就不怕任何场景了。我们在文字定义时也模拟一下,设置阴影和阴影偏移试一试:

fill:'white',

shadow: {

offsetX: 2,

offsetY: 2,

blur: 4,

color: 'black',

},

看一下使用前和使用后的效果对比:

HTML5数据可视化第一弹:彩虹爆炸图

使用阴影后不但文字更清晰了,而且也增加了立体感,效果还是不错的。下面图显示在应用在节点上的效果:

HTML5数据可视化第一弹:彩虹爆炸图

可见不论什么颜色,都能比较好的勾勒出文字轮廓,保持清晰可读。

三、生成彩虹颜色

关于颜色,是一个有趣的话题。对于广大程序猿来说,颜色是一个既简单又困难的东西。我们随手就能写下’red’, ‘green’, ‘orange’, ‘yellow’这样的色彩斑斓的颜色,还能保证没有语法错误;我们还会写’#FF55AA’、’#0c0’、’RGB(0,204,0)’、’ RGB(0%,80%,0%)’这样的各种颜色写法;我们也明白RGBA的含义和用途。但是,我们很少能把一个demo写的颜色很好看、很搭配。关于颜色和配色以后再专门讨论。这里我们只想自动生成一圈彩虹一样的颜色。用我们熟悉的RGB方法好像比较困难了。于是想起了那个HSV的颜色定义方法,它貌似很适合解决这个问题。

HSV颜色模型定义了色调H、饱和度S和亮度V,由A. R. Smith在1978年创建的一种颜色空间。其中H用一圈360度表示所有颜色,从红色开始按逆时针方向计算,红色为0度。饱和度S从0到1,越大越饱和。亮度V从0到255(也可以转换为从0到1,方便使用),越大越明亮,越小越暗淡。

HTML5数据可视化第一弹:彩虹爆炸图

Js里面并没有直接处理HSV颜色的函数。不过用下面的代码很方便可以从hsv转为rgb:

HTML5数据可视化第一弹:彩虹爆炸图

写一个对应的js函数也很简单:

/* h, s, v (0 ~ 1) */

function getHSVColor(h, s, v) {

var r, g, b, i, f, p, q, t;

if (h && s === undefined && v === undefined) {

s = h.s, v = h.v, h = h.h;

}

i = Math.floor(h * 6);

f = h * 6 - i;

p = v * (1 - s);

q = v * (1 - f * s);

t = v * (1 - (1 - f) * s);

switch (i % 6) {

case 0: r = v, g = t, b = p; break;

case 1: r = q, g = v, b = p; break;

case 2: r = p, g = v, b = t; break;

case 3: r = p, g = q, b = v; break;

case 4: r = t, g = p, b = v; break;

case 5: r = v, g = p, b = q; break;

}

var rgb='#'+toHex(r * 255)+toHex(g * 255)+toHex(b * 255);

return rgb;

}

再回到我们的彩虹爆炸图。每一个节点对应的所在角度(中心角度)决定了它自己的颜色值。所以,我们可以直接根据这个角度得到颜色的h。然后,为了让彩虹逐渐一圈一圈变淡,再把s饱和度从1逐圈递减(例如0.1),产生变淡的效果。为了防止圈太多最后看不清,减到0.2到0.3左右可以停止递减。

var fromAngle=node.getClient(‘fromAngle’);

var toAngle=node.getClient(‘toAngle’);

var level=node.getClient(‘level’);//节点在第几圈

var h = (fromAngle+to)/2 % 360 /360; //中心角度,并转换为弧度

var s = Math.max(0.2, 1-level*0.1);//每圈s递减0.1,直到0.2为止

var v=1;

var color=getHSVColor(h, s, v);

这样就获得了一圈颜色。实验效果如下:

HTML5数据可视化第一弹:彩虹爆炸图

如果相对某个节点的颜色做特殊处理,例如强制为橙色来凸显,我们可以在数据中定义时加个标记,设置颜色时候直接使用而不用计算即可。

{name:'浦东新区', value: 2600, color: '#FE9A2E'}

HTML5数据可视化第一弹:彩虹爆炸图

接下来要实现鼠标划过节点,自动计算路径、高亮路径节点、暗淡非路径节点。为了方便路径寻找,程序把每个节点的下一圈子数据定义为子节点,子节点通过getParent()函数可以直接获得父对象。这样,通过不断getParent就可以获得整个路径上的节点,并修改其颜色为预设颜色,实现高亮效果:

var node=highlightedNode;

while(node){

node.setClient(‘color’, node.getClient(‘color.original’));

node=node.getParent();

}

对于非路径节点的颜色,可以设置为预设颜色但饱和度为0.1的淡颜色 ,让它变淡,以便突出高亮路径:

var color = getHSVColor(h, 0.1, v);

node.setClient(‘color’, color);

四、动画效果

最后,为了图形更生动,使用了一些动画效果。首先想到的就是图形出来时候,用动画从小到大发散开来,会很动感。这样做需要用动画函数来驱动每一个节点的半径位置,从0增加到所在的半径位置,如果大家一起设置,整个图就会动起来。这里用了一个动画函数来驱动,并使用了网上常用的easing函数来控制,避免线性的动画太死板:

new Animate({

from: 0,

to: 1,

dur: 3000+level*100,

easing: 'elasticOut',

onUpdate: function (value) {

node.setLocation('pie.location’, value);

},

}).play();

上面定义的动画,用3秒钟跑完,用'elasticOut'的easing方式。每一帧,修改node的位置信息。这样就完成了橡皮筋一样的环形弹出散开效果。

另外,导航条的出来也比较突兀,这里也使用一下动画,让它从左到右慢慢伸出:

new Animate({

from: {x:x1, y:y1},

to: {x:x2, y:y2},

delay:50,

type: 'point',

dur: 1000,

easing: 'bounceOut',

onUpdate: function (value) {

node.setCenterLocation(value.x, value.y);

},

}).play();

和上一个动画的不同之处在于这里使用了{x、y}的point结构,每一帧直接更新节点位置。同时设置了50毫秒的delay,让动画有一点点粘性停滞,不至于太突兀。效果不错。

HTML5数据可视化第一弹:彩虹爆炸图

至此,彩虹爆炸图基本上就做的差不多了。使用起来也很简单,只要准备一些json数据就可以了,下面是一些有趣的数据做出来的效果。感兴趣的同学可以发邮件到 tw-service@servasoft.com 索取代码。

HTML5数据可视化第一弹:彩虹爆炸图

实际应用在项目中的示意图。如果你也希望项目中用一下彩虹爆炸图,欢迎给我发邮件索取:info@servasoft.com

HTML5数据可视化第一弹:彩虹爆炸图

HTML5数据可视化第一弹:彩虹爆炸图

Similar Posts:

  • HTML5数据可视化学习之路---eChart起步

    这几天在学习HTML5,准备从FLEX转型了.看了一些基础的学习教材,也写了一些基础例子,但是仍然没决定从什么地方入手.今天在网上无意间发现了一个很牛叉的图表库EChart,并且这个项目还是百度团队开发的.优点在我看来除了官方说的那些特性之外最好的就是,中文稳定非常全(因为毕竟是我们中国人自己开发的). 开始看了官方的Dome真的是非常丰富,基本上现在用到的数据可视化的常用图表都有了.于是开始找一个例子开始来进行我的第一个eChart项目吧. 我选择的是地图选择器和标准地图两个组件,因为现在开发

  • 用D3.js进行医疗数据可视化 (四) 堆积区图 (Stacked Area Chart)

    介绍 在之前的文章<用D3.js进行医疗数据可视化 (一)折线图>中,我们可以看到对于所可视化的医疗卫生机构诊疗人次数线图,最下部的几条线几乎重合在一起,而且几种机构类型相互包含,关系比较混乱.因此在这篇文章中,我们尝试一下用堆积区图(stackedarea chart)来强调它们之间的对比. 代码 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title&g

  • 开源的数据可视化工具

    Linux 上的数据可视化工具 5 种开放源码图形化工具简介 M. Tim Jones (mtj@mtjones.com), 资深软件工程师, Emulex 简介: Linux 上用来实现数据的图形可视化的应用程序有很多,从简单的 2-D 绘图到 3-D 制图,再到科学图形编程和图形模拟.幸运的是,这方面的工具有很多开放源码实现,包括 gnuplot.GNU Octave.Scilab.MayaVi.Maxima 等.每个工具都有自己的优缺点,并且都是针对不同的应用程序而设计的.对这些开放源码图

  • 数据可视化入门:柱状图、雷达图等六种基本图表的特点和适用场合

    "数据可视化"可以帮助用户理解数据,一直是热门方向. 图表是"数据可视化"的常用手段,其中又以基本图表--柱状图.折线图.饼图等等--最为常用. 用户非常熟悉这些图表,但如果被问道,它们的特点是什么,最适用怎样的场合(数据集)?恐怕答得上来的人就不多了. 本文是电子书<Data Visualization with JavaScript>第一章的笔记,总结了六种基本图表的特点和适用场合,非常好地回答了上面的问题. 序言 进入正题之前,先纠正一种误解. 有

  • 搞懂5种数据可视化方法,胜任90%热门信息图设计

    概念 借助于图形化的手段,清晰.快捷有效的传达与沟通信息.从用户的角度,数据可视化可以让用户快速抓住要点信息,让关键的数据点从人类的眼睛快速通往心灵深处. 数据可视化一般会具备以下几个特点:准确性.创新性 和 简洁性. 常用五种可视化方法 下面从最常用和实用的维度总结了如下5种数据可视化方法,让我们来一一看一下: 一.面积and尺寸可视化 对同一类图形(例如柱状.圆环和蜘蛛图等)的长度.高度或面积加以区别,来清晰的表达不同指标对应的指标值之间的对比.这种方法会让浏览者对数据及其之间的对比一目了然

  • 数据可视化知识贴②:似曾相识面积图

    面积图正如我们平时所看到的大山那样,斗转星移沧海桑田,山依然是山. 看上去样子都差不多,但是仔细读来,却又内藏玄机. 面积图也是一种随着时间变化的图表,而且很稳重. 无论你是要梳理出每个月各部门的净收益,或者想看看从上世纪50年代以来各个音乐流派的普及流行程度,相信我,在那些与时间相关的图表中,没有什么比面积图都可以更满足你的需求了. 下面就让我们来好好认识一下这个似曾相识的面积图吧! 这就是前面提到的20世纪各流派音乐流行交互面积图. 了解面积图 面积图描绘了时间序列的关系,不过与线型图不同,

  • 数据可视化Data-Driven Documents

    http://alignedleft.com/tutorials/d3/ D3简介 D3全称:Data-Driven Documents D3是一个很神奇的基于Javascript的在网页上实现数据可视化的工具.作者是原可视化工具Protovis开发小组的成员Mike Bostock,现Protovis已经不再更新,Mike Bostock将主要精力转向以Protovis为基础的D3,更好的支持大数据处理和动态交互.已发布到V2版本,作者也提供V3版本,但尚未正式发布. 掌握D3的基础: 1.熟

  • 推荐14款基于javascript的数据可视化工具

    推荐14款基于javascript的数据可视化工具 概述:随着数据可视化概念逐年火热,有较多优秀的图表开源库和制作工具脱颖而出,下面,我们就拿其中比较有名的 14个产品进行简要介绍. 1.AnyChart 链接:http://www.evget.com/supplier/227 AnyChart 是基于 Flash/JavaScript(HTML5) 的图表解决方案,它可以轻松地跨浏览器.跨平台工作.除了基础的图表功能外,它还有收费的交互式图表和仪表功能.它可以通过 XML 格式获取数据,该方式

  • 28个富数据可视化工具(转)

    我们当前正与多家客户合作, 都是关于Web应用(重新)设计.所有客户都有富数据应用并且急需数据可视化以帮助他们的终端用户快速有效的分析数据. 有趣的是这些客户处于不同的行业并使用彼此不同的技术.于是我们收集了28种可视化工具来创建图形(graphs), 甘特图(Gantt charts),图表制作(diagrammers), 日程表(calendars)/调度表(schedulers),计量表(gauges), 测绘(mapping), 数据透视表(pivot tables),OLAP多维数据集

  • 大数据可视化产品Datawatch的功能介绍,以及产品

    Datawatc可以处理多样类型的数据,包括结构化.半结构化以及非结构化的,具有实时的处理速度,可以处理实时的.高延时的和低延时的:具备可视化的处理环境,可以产生富有冲击力的图表.动态导航以及时间序列的数据.具体表现在: 关于Datawatch,36大数据专稿:大数据可视化.实时性分析的工具--Datawatch (1)专为金融领域打造的数据呈现解决方案 Datawatc支持OHLC图,子弹图,分布图,树形图,点阵图等图形展示.支持自定义时间线回放数据,支持数据过滤:支持数据行转列和列转行:支持

Tags: