zoukankan      html  css  js  c++  java
  • D3js初探及数据可视化案例设计实战

    摘要:本文以本人目前所做项目为基础,从设计的角度探讨数据可视化的设计的方法、过程和结果,起抛砖引玉之效。在技术方案上,我们采用通用web架构和d3js作为主要技术手段;考虑到项目需求,这里所做的可视化案例都是数据演示工具,不是数据探索工具。其中所用截图,并非最终效果图。

    一.             基础说明

    1. 1.       基础技术

    使用D3js绘制图形

    图1,五彩斑斓的d3js

     

    D3js是应用在web开发上的开源JS组件库,是一个数据可视化工具。D3的全称是Data-Driven Documents(数据驱动文档),在github上关注数量超过了2万人,是非常受欢迎的开源工具。使用d3的有开发者,有设计师,有艺术家,资料非常丰富(虽然中文的很少)。D3其核心在于SVG可伸缩矢量图形。从数学上讲,如果说位图是用矩阵描述数据元,那么SVG等矢量图就是用方程式描述数据元。SVG有放大不失真的效果。关于SVG的更多介绍可以访问http://www.w3school.com.cn/svg/svg_intro.asp

    注意:

    a)         SVG技术不能兼容IE8及更低版本的IE浏览器。如果想要IE8使用d3,请用r2d3.js(一个结合了 Raphael.js的扩展库)。但是考虑到即使如此,IE7依然无法兼容,不如放弃对二者的兼容性考虑。如果实在要兼容IE,要么用VML(微软出品的绘图工具,缺点是复杂),要么预渲染成位图(需要放弃一些交互效果)。

    b)         SVG在浏览器端实现的方法是对每一个点和边新建一个对象,虽然这样做令我们操作它变得更容易(我们可以直接操作dom,代码像jquery一样简洁),但是节点数量如果过多就会消耗太多的系统资源。例如论坛里一个朋友使用d3绘制超过12000个节点的图,直接导致每个试图打开它的浏览器都崩溃了。这个时候如果不愿意做简化那么应该试试canvas绘图。

    1. 2.       制作流程

    D3js只是一个可视化工具。就像学会了photoshop工具不等于能画出好看的CG一样,光会用D3js的API,依然不能保证可以设计出优秀的可视化作品。好在d3js已经提供了很多经典案例以供学习。初学D3js的最好方法还是以案例为切入点,通过修改开源的案例来快速实现想要的效果。如此积累到一定程度便可主动设计新案例。可以说跟从临摹开始的美术学习完全一样,设计制作可视化案例的基本流程是:

    1)         分析需求——确认重点表现对象

    2)         分析数据来源——确认数据维度和特征

    3)         寻找参考案例——依照需求和数据来源寻找类似案例

    4)         设计图形——纯设计角度制作PSD效果图

    5)         使用静态数据制作源程序——生成静态的网页代码

    6)         数据预处理——对不同的数据格式和来源进行过滤

    7)         使用动态数据测试和修改源程序——生成可用的程序

    8)         迭代

    http://sulab.org/2013/02/data-chart-plugin-beta/这篇来自SU lab的文章,描述了“基因组导航系统”数据可视化案例的制作过程,很好的反映了以上制作流程。

    当然,在具体操作时,肯定要涉及数据格式变换、数据预处理等内容。我们通常约定数据格式为json,或者csv.但是本文只从设计的角度探讨数据可视化的设计之道,起抛砖引玉之效,不讨论数据获取,数据预处理等细节。

    3.       设计标准

    从使用场景上来说,数据可视化分为两类,一类是数据表现工具,用于把设计师所知道的数据用人们更易理解的方式表达出来;一类是数据探索工具,为了帮助未知事物的研究。考虑到项目需求,这里的案例都是数据表现工具。从技术角度上说,d3js也最适合做数据表现工具。

    一个合格的可视化案例通常需要包含四个方面:informative(饱含信息的),efficient(高效的)、Novel(新颖的)、Aesthetic(有美感的)。

    以上四者中,informative最为重要,提供获取信息的途径是可视化成功与否的关键;Efficient次之,必须尽可能直截了当地获取信息,同时不牺牲任何必要的复杂性;Aesthetic是以上二者的适当补充,而novel通常只是Effective information的副产品。

    大量平庸的可视化设计完全基于标准格式,如bar chart(条形图)、pie chart(饼图)、line chart(线图)、bubble chart(散点图或气泡图)等。虽然这些图提供了便捷方式并且具有自明性,但是其标准性和普遍性意味着无法达到新颖性。

    故而在理想状态下,应尽量采用新颖、高效的设计方案,突出结论及提高视觉魅力;即使采用标准图形,也要有足够的交互特性使之与众不同。

    4.       相关资源

    找参考案例第一选择是d3官网https://github.com/mbostock/d3/wiki/Gallery

    除此以外还有http://techslides.com/over-1000-d3-js-examples-and-demos/ (有超过1000个例子)Github上的d3js源码:https://github.com/zhangdiwaa/d3

    二.             实际案例

    案例一:区域报修热点图

    1.         需求分析

    系统中需要统计每个区域的报修次数,并以图形化的方式显示出来。地区又可以细分为楼宇和房间,每个部分可以分别统计个数也可以汇总出总数。其中重点在于,同层次下不同地区之间报修数量的对比。

     2.         数据分析

    需要表现的数据维度:2维,地区和报修数量。

    a)         地区,特点是多层次,地区可以分为区域、楼宇、房间,呈树形包含关系;底层节点的数量可能会比较多,不可预估。但观察者注重的是上层节点,偶尔会关注底层节点。

    b)         报修数量,特点是数字,根节点的值通过叶节点计算。

    3.         寻找参考案例

    对于这类数据可用的统计图类型极多。常用的统计图类型有堆栈图、树、矩阵、汽泡图等,都可以表现这种2维数据。这里有个很好的范例,展示了同类型数据采用不同统计图展示的效果:http://datavlab.org/datavjs/#stream,这里我们只学习设计思想。

    4.         制作统计图

    在经过对比后,我个人认为Circle Packing或者bubble chart可以比较直观地表现数值信息和不同区域之间的对比关系。并且Circle Packing还有一个优点,就是可以有效地屏蔽多余的数据,一开始只展示上层节点的关系,当用户有需要的时候再点击对应的圆圈展示下层节点——这是显示多级层次数据的必要手段。现在做可视化离不开交互,故而这里我选择一个带有交互的案例作为参考模版。它可以很有效地表现出双维度的层次、对比关系。

    参考案例:http://mbostock.github.io/d3/talk/20111116/pack-hierarchy.html

    图2,仿照Circle Packing案例我们制作的初始统计

    5.         维度增加

    原始的统计只有区域、报修数量两个维度(虽然区域这个维度是多层次的)。为了增强功能,我们需要增加一个重要的维度——时间。如此整个可视化案例就可以反映时变特征,方便用户追寻历史信息。可以说在很多领域时变特征分析是数据分析和可视化方面表现的重点。

    对于统计图而言增加时间维度的最简单方法是做时间轴。如果能做到随着时间轴拖放的交互效果就更好了。不过一开始我们只做一个下拉列表来表示不同年份的时间统计,等这个功能做好后,再做时间轴。(类似的参考案例:http://budzet.aws.af.cm/

    图3,开始先用下拉框调试,以后改成时间轴

    更进一步,我们希望把报修类型维度也加入图中。报修类型种类一般在10个以内。将这个维度加入图形,如果反映出某个地区常出现的报修类型,那么对于管理员此类信息是非常有用的。

    在表现上,为了避免信息过载,这一类附加信息我们通常使用tip、附加图形的方式表示。例如图4表现报修类型的饼图和原图结合的方式,这种多图结合的方式对比效果表达得好,缺点是实现难度大,设计难度大,并且可能会给用户造成误解,故而必要时需要增加文字提示。图5使用了tips与原图结合的方式。Tips是最常用的增加维度的方法,但是和原图耦合度不高,产生的对比效果较差,优点是容易实现,用户理解障碍也小。

    图4,饼图与原图结合的方式呈现更多维度信息

    原创效果

    图5:tips与原图结合的方式呈现更多维度的信息

    使用tips的参考案例有:

    http://www.brightpointinc.com/interactive/budget/index.html?source=d3js

    http://bl.ocks.org/Caged/6476579

     6.         总结

    至此,这个统计图中已经包含了4个维度(地区、报修类型、时间、报修数量),一个层次关系(地区的包含关系),两种直接的对比关系(区域之间报修数量的关系、 区域内报修类型之间的数量关系),一种间接的对比关系(不同区域的报修类型的数量关系)。可以说足够强大了。为了向参考过的案例表达敬意,我称其为zooming Circle Packing with tips and timeline统计图。

    我们可以总结:单维度上带有层次关系并且总维度较少的统计数据 和 强调单维度的对比关系的需求,适合此zooming Circle Packing统计图显示。这种zooming Circle Packing图,在展示强烈对比关系时非常有效,但是确实不适合太多维度的数据。如果要增加新的维度,那么我们往往只能采用上述的办法,增加新的下拉列表、tips、时间轴等与原图耦合度不高的部件来显示。这种部件越多,用户理解起来也会越困难。增加一个两个倒还可以接受,如果维度过多,应该试试tree map等统计图(不过那也更难理解了),或者拆开为多图显示。

    案例二:维修组工作量对比图

    1.       需求分析:

    项目中还有一个需求。就是统计每个月维修组工作量。一个维修组可能有多个人,每个组、每个人的工作量都要统计并量化的表示出来。维修组和组员的数量一般不会很多。需求重点:反映组之间的工作量对比,若能同时反映每个人的工作量对比则更好。

    2.       数据分析:

    数据维度:维修组、时间、工作量

    a)         维修组:带有2级层次,维修组——维修人员,二者呈树形包含关系。维修组及其成员的数量都不是很多。

    b)         时间:普通时间轴。从系统开始运行后计算。以月为最小单位。

    c)         工作量:维修人员处理的工单数记为其工作量,维修组的工作量为组内成员的工作量之和

    3.       寻找案例:

    我们可以看出,这个数据集跟上一个区域热点图的数据集有很多相似之处,都有一个带有层次关系的维度,都带有时间轴,总维度数也不多,故而理论上也可以用zooming Circle Packing图来实现。但是也有两个显著区别,其一是维修组的层次和数量不像区域那么多,其二,需求要求我们能同时展示工作组和人之间的对比。考虑到这两点不同,和人们容易审美疲劳,不能用zooming Circle Packing图,需要重新寻找案例。

    寻找的对象显然是类似zooming Circle Packing这样可以显示层级关系同时又能反应总和数据对比关系的统计图和主题图,例如tree,tree map,bar chart, stack chart,line chart等等。这里我找到两个带交互效果的案例:

    http://mbostock.github.io/d3/talk/20111116/bar-hierarchy.html (带有层次的柱状图)

    http://bl.ocks.org/mbostock/3943967(可在堆栈和柱状图组之间变化的图)

    经过对比我选择了后者,因为它堆栈和柱状图组都能在用户不做操作的情况下反映底层之间的对比关系,适合表达满足“同时反映每个人的工作量”的需求。故而我对其进行修改,做出了如下初始统计图:

    图6维修组工作量对比图的柱状图组效果

    图7维修组工作量对比图的堆栈图效果

     

    4.       维度增加

    从上面两图可以明显地看到,组之间的工作量对比、甚至人员之间工作量的对比表达得很完美。再配合一些动画效果已经足够美观。最后就是增加一个时间轴,来反映时间变量。

    必须指出的是,对于这种2D图形,时间轴是最后加上去的第三维,用户在查看时间变化时并不像时间轴作为2D图形的X轴和Y轴时那样直观。对此,有一些弥补手段,例如将上个月的统计图做透明度减淡处理覆盖在这个月的统计图之上,或者用另开一个时间窗口用来描述,不过这些办法效果都一般,所以也有用3D或者伪3D图形去表现3个维度的数据的(例如http://charts.animateddata.co.uk/uktemperaturelines/)。但是考虑到需求上重点是突出组和数量这两个关系,所以我这里就不做这些缝缝补补了。

    最后为了明确描述信息,丰富内容,可以采用增加tips的方法,在用户鼠标点击(click)或者悬停(hover)的时候显示tips,把维修人员姓名、月工作量、月总分、月平均分这些信息显示出来。本质上还是用tips增加维度的方法。

    5.       总结

    事实上一开始这个图的设计内容有很多,最初计划将时间、维修组、维修人员、工作量、维修人员的用户评价总分、维修人员的用户评价平均分这6个纬度的数据全表现在一个图上,同时突出时变特征分析和人员之间的对比关系。但是这么复杂图用纯2D图形是很难表现的,可以想象的结果是增加一堆选项按钮,勉强将所有维度的数据绑定到一个图中。或者一个大图多个小图来表现,这样不仅做起来难,做好后用户用起来也难。应该简化内容,一幅图里就表现主要需求,太多的内容不如分开,如此就有了第三个案例,维修人员时序评价图。

    案例三:维修人员时序评价图

    1.       需求分析:

    既能按时间顺序表现维修人员的评分变化,又能同时比较多个维修人员。

    需求重点:时序变化,多人比较

    2.       数据分析:

    数据维度:维修人员,时间,平均分,总分

    a)         维修人员:单一,无层次。

    b)         时间:普通时间轴。从系统开始运行后计算。以月为最小单位。

    c)         总分:维修人员 当月评价总分

    d)         平均分:评价总分/当月接单数

    3.       寻找案例:

    这个案例无疑是最好找的,同时显示多个变量的时序变化,line、bar是最为常用的表现方式。我们可以最快速度想到的类似案例无疑是股票走势图——多个股票的对比是多几道变化的线。这种统计图由于常见,有一种不言自明的效果。

    这有一个非常好的案例:

    法国人的命名变化:http://dataaddict.fr/prenoms/#amar,amaury,anae,andrew

    这个案例的优点在于:大小自适应,漂亮的动画效果,滑动时间轴,可由用户选择对比对象,好看的tips。

    以这个案例为模版,各种表现时序对比关系的报表手到擒来。例如把人名换成维修人员,把人名出现的数量换成总分,就已经是很不错的统计图了。最后,平均分和总分是两码事,数值差距大,不适合在一个图中表现,拆成两个图就好。

    图8,一个十分好的案例,法国人命名的变化

    图9,使用两个图表展示不同纵坐标数值的案例

    http://www.cotrino.com/starpaths/

    本来这一类时序对比关系的报表就比较成熟。再考虑到工时因素,不做多余的设计。

    那么思路很明确了,维修人员时序评价图,采用类似图9的双图显示方式,同时采用类似图8的动画效果。这样已经满足需求的需要了。

  • 相关阅读:
    无缝轮播图
    瀑布流之ajax
    进阶版轮播图
    桌面特效
    3D模型文字动画
    Razor 常用方法
    easyui常用
    C#
    Redis设置记录
    日志三剑客ELK
  • 原文地址:https://www.cnblogs.com/zhangdi/p/4026375.html
Copyright © 2011-2022 走看看