D3数据连接:进入

标签: D3  数据科学

引言:数据连接是D3中的面包和黄油。D3不提供制图的基础函数,相反,它靠的是数据连接。数据连接可以让页面元素进入网页,一旦进入,可以修改、更新及退出。本文将主要介绍“进入”部分。
本文选自《图说D3:数据可视化利器从入门到进阶》。

什么是数据连接

  顾名思义,数据连接肯定是将数据和某些东西连接起来。这些东西是网页上的一个或一组——< rect>、< circle>、< div>等所有值得怀疑的常见元素。具体一点,就是这些常见元素的一个D3选择集。
  在深入了解之前,让我们忘记D3一会儿。现在,想象有一幅可交互的图形,可以是你以前看到过的、自己写的或者刚刚想象出来的,其中有一些代表数据的图形及一些用来控制某些数据显示与否的按钮。当你点击这些按钮,图形会发生变化:位置偏移了,发光或者闪烁,颜色也变了,甚至可以一起从屏幕中飞出——要多疯狂有多疯狂。
  现在,不管你的图形多么复杂,包含了多少数据,从基础层面看,涉及的这些形状(或线、文本标签、颜色及纹理)都只是在做以下3件事情。

  • 显示在页面上——没有数据和图形就不可能有数据可视化,所以图形需要显示出来。
  • 变换——当你点击按钮或调整滑块,图形的属性会按你想看到的最新数据进行更新。
  • 离开页面——有时,如果一个或多个图形表示的数据不再有效,其会从页面完全移除。

就是这样的3件事情。一个交互式图形就像一座剧院,当演出的时候,演员进入舞台,表演节目,然后退场。在数据可视化中,形状——或更笼统地说,图形元素——进入页面,更新自身,然后退出。
  数据连接充分利用了上述的初步想法。使用时,可以通过指令让图形元素进入、更新和退出。(实际上,我直接从D3中搬来了“enter”、“update”及“exit”这些词。)
  此外,D3让你可以基于数据执行上述所有操作。D3通过一种称为“数据绑定”的技术来达成这种能力。无论何时执行数据连接,数据会真正被关联,或绑定到元素上。这真的太方便了,D3让你可以非常轻松地绑定数据了。所以,你会说:“好了,矩形,你所绑定的数据是多少?35?嗯,好吧,希望你的宽度也正好是这么宽。”
  为了说明数据连接是如何工作的,我打算引入一个新的示例—— 一个涉及数据连接基本概念各方面知识点的示例。为了构建之前那幅人口分布条形图,我们也会引入数据连接,但不会描述得那么完整。所以,虽然有点跑题,但是引入一个新示例将有助于我们研究数据连接的方方面面。
  本文只涉及数据连接知识的一部分,重点在其整个生命周期中关于“进入”的部分。在后面的推送中,我们会用同样的示例来详细阐述“更新”和“退出”部分。
  好了,我们开始。
  假设你有一个朋友,名字叫Frank。Frank有一个癖好是喜欢看明星八卦杂志和各种小道报刊。《美国周刊》、《人物》及《国家调查者》等,就是那种你在杂货店排队结账,百无聊赖时会瞥见的刊物,Frank一定会有强烈的兴趣。问题是,他其实并不关心Kim和Kanye的近况,他只是想知道一件事情:谁上封面了?
  Frank最近一直在关注20多种不同杂志期刊封面上的特色名人,一个月内会有约50张不同的封面——已经持续了1年。此外,他还研究了过去4年各个封面人物的情况。“我认为那些在任何时刻都被人们议论的名人体现了这个国家的精神面貌”,Frank啰唆道。你有你的怀疑,但当Frank找到你并请求你帮他将这些信息做成可视化图形时,你也没法拒绝。
  Frank的想法是:基于他所收集的近5年的数据,按月显示最热门的5个名人。他希望这个可视化图形是可以交互的,并具有动画效果,但是他不知道图形应该做成什么样子。然而,你是有想法的。你在笔记本上画了几分钟,交给Frank一幅草图,然后开始解释。
               【图1】
                       为Frank准备的草图

  “图形展示了数据集中最老的,也就是2009年1月五大名人的列表”,你向他解释道。然后,每一个名人的名字是一个条形,代表了他(或她)这个月在杂志封面上出现的次数。这样,哪个名人拥有主导地位就一目了然了。Frank有两种方式切换到后续月份:他可以按下播放按钮,然后坐下欣赏(因为图形会自动按月显示);或者拖动滑块到指定的月份。当图形从一个月份变换到另外一个月份,新的名字会进入排行榜,旧的名字会退出,还有一部分会在列表上上下移动,同时条形的宽度会扩展或收缩至更新后的数值。“好极了!”Frank赞叹道。然后,他把剩余的3000行数据也一并发送给你。
进入,更新,退出……D3为此而生!

进入并绑定数据

  假设你已经整理了一些数据,为每个月、每个名人都增加了封面,并进行了排序。下图是你整理的前3个月的信息,也就是2009年1月到3月的信息(这些数值当然都是杜撰的)。
                   【图2】
                         前3个月的数据

  以下是关于这些数据的一些解释。

  • 封面人物的数量并不总是刚好等于50。这是因为有的封面包含两个名人,这种情况下,该封面算是这两个人的。
  • 1月所有封面上仅有4位名人,大部分期刊都在关注Brad Pitt和Angelina Jolie的故事。(这就是Frank所说的国民精神所在?)
  • 2月类似于1月,除了《世界新闻周刊》,其他杂志的封面人物都是著名的“蝠孩”。

通过JavaScript来组织这些数据的一种良好方式是创建一系列对象数组。例如,1月我们有如下数组。

var janData = [         
      {name:"Angelina Jolie", covers:20, rank:1},
      {name:"Brad Pitt", covers:18, rank:2},
      {name:"Jennifer Aniston", covers:10, rank:3},
      {name:"Britney Spears", covers:8, rank:4}
];

  你能看出来为什么这个结构很友好吗?数组janData包含4个数据对象,每个对象包含一个数据点该有的所有信息。我们将在第7章阐述有关数据结构的更多细节。
  好了,要事优先:我们需要在页面上显示一些图形。现在,让我们先忘掉这些条形,并且仅从这些人物的名字开始。我们可以用for循环为每个名字添加一个文本节点,但是我们不打算这么做。忘掉for循环,我们正在考虑数据连接,我们想让文本“进入”页面。
  具体方法是:我们先为当前页面上的所有文本元素创建一个选择集,然后为其连接数据。但是,等等……我们的页面是空白的,现在还没有文本元素!所以,“选择所有文本元素”到底意味着什么?
此处展现的就是D3进入阶段的“魔法”——通过d3.selectAll()创建一个并不存在的元素的选择集。在这种情况下,由于我们想让文本进入页面,因此可以通过d3.selectAll(“p”)选择所有这些还不存在的段落元素。这个概念如下。
                 【图3】
                       一个空的选择集
                       
  然后,你在这个选择集上调用了两个方法,分别是data()和enter()。这一记“组合拳”产生了真实的惊人效果:其为数据集中的每个数据点都创建了一个对象。是的,就是这样——你不必告诉D3你的数据集有多大。你只要将其与一个空选择集进行连接,它就会为你创建正确数量的对象。
             【图4】
                      data()和enter()的魔法

  一开始,这些数据只用来占位——文本元素还没有真正添加到页面上。为了做到这一点,我们就得用上我们的老朋友append()了。我们将为那些占位数据都附加一个段落元素。
             【图5】
                     用文本元素替换占位数据

  现在,我们已经在页面上放置了4个文本元素,但是其中还没有任何文字,所以我们的页面是空白的。如何让那些名人的姓名显示在正确的位置呢?奥秘就在data()方法中。该方法实际上执行了一次数据连接——当D3执行数据连接时,它将数据绑定到元素上。所以,每一个文本元素实际上都会有一个数据与其关联或绑定,正如上图所示。
  D3让我们可以很容易地绑定数据,所以我们可以通过数据来告知文本应该显示什么内容,以及在哪里显示:“好了,元素们,看看你们自己的数据点。你的名人名字叫什么?Angelina Jolie?好的,这就是我想让你的文本显示的内容。此外,它应该排在第几个?第1个?好的,你就排到顶上吧!”
  本文选自《图说D3:数据可视化利器从入门到进阶》,点此链接可在博文视点官网查看此书。
                    图片描述

版权声明:本文为broadview2006原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/broadview2006/article/details/80128574

智能推荐

websocket基本原理

HTTP中一个request只能有一个response。而且这个response也是被动的,不能主动发起 因此过去的服务端推送信息是通过客户端不停的轮询实现的 websocket是双向通信协议,提供了服务端主动推送信息的能力 需要客户端(浏览器)和服务端同时支持 如果经过代理的话,还需要代理支持,否则有些代理在长时间无通信时会自动切断连接 因此WS为了保证连接不被断掉,会发心跳 WebSocket...

mybatis+ehcache二级缓存

导入jar包 mapper.xml文件开启二级缓存 pojo类实现序列化接口 配置ehcache.xml 测试...

python+opencv实现图像拼接

任务 拍摄两张图片去除相同部分,拼接在一起 原图 结果 步骤 读取两张图片 使用sift检测关键点及描述因子 匹配关键点 处理并保存关键点 得到变换矩阵 图像变换并拼接 代码实现 扩展 这里对右边图像进行变换,右边变得模糊,可以修改代码对左边图像变换 这里只有两张图片拼接,可以封装实现多张图片拼接 可以修改代码实现上下图片的拼接...

python_sklearn机器学习算法系列之AdaBoost------人脸识别(PCA,决策树)

          注:在读本文之前建议读一下之前的一片文章python_sklearn机器学习算法系列之PCA(主成分分析)------人脸识别(k-NearestNeighbor,KNN)         本文主要目的是通过一个简单的小...

memmove函数与memcpy函数的模拟实现

memmove函数和memcpy函数都是在内存复制任意类型的,但是它俩也有区别。当源区域和目标区域有重复的,memmove函数会复制缓冲区重叠的部分,而memcpy相反,会报出未知错误。 下面给出两个函数的实现 首先,memmove函数。 实现的基本原理如下图。 具体代码如下: memcpy函数的实现很简单,就直接给出源代码了...

猜你喜欢

SpringFramework核心 - IOC容器的实现 - 总结

1. 概述 把Spring技术内幕第一章和第二章过了一遍,也做了一些笔记, 对IOC容器的实现有了一定皮毛理解,现在跟着源码再过一遍总结一下IOC容器的初始化,Bean的初始化的过程,做一下总结 ① IOC容器和简单工厂模式 在开始之前,先想想我们平时是怎么使用IOC容器为我们管理Bean的,假设我们要把下面的User类交给IOC容器管理 我们不想关心如何创建一个User对象实例的,仅仅在需要他的...

Python和Django的安装

个人博客导航页(点击右侧链接即可打开个人博客):大牛带你入门技术栈  一、下载并安装Python Python 官方下载地址:http://www.python.org/ftp/python/ 我们这里选择的是 Python 2.7.2 。虽然目前最新版是Python 3.2.2, 但是Django目前还不支持 Python 3.2.2。 安装步骤很简单,双击安装包开...

OpenStack代码贡献初体验

为什么80%的码农都做不了架构师?>>>     OpenStack如今已成为开源云平台中的明星项目,得到广泛关注。OpenStack的优秀出众依赖于众多开发者的努力,在享受其带来的便利与快捷的同时,为其做一份贡献也是一个开发者的义务。  在前段时间的OpenStack的测试过程中,我发现Nova项目中的一个Bug,于是向社区提交了Bug报...

SQL Server之8:sql查询每个学生得分最高的两门课

这是一道面试题,今天有空把它记下来,以后遇到此类问题作个参考!刚一看到这个题目,估计好多人都会想到关键字top,其实这里用到的关键字是partition, 好了,先看看表结构,及数据吧!     接下来看一看partition的功能,执行语句   结果如下:   到这里一目了然知道最终结果了!   View Code     &...