前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >《使用D3设计交互式图表》简读笔记|可视化系列31

《使用D3设计交互式图表》简读笔记|可视化系列31

作者头像
蛰虫始航
发布2020-05-14 16:53:16
3.7K0
发布2020-05-14 16:53:16
举报
文章被收录于专栏:蛰虫始航蛰虫始航

本文是《数据可视化实战:使用D3设计交互式图表》[1]的简要版读书笔记,通过约4000字概览如何用D3做可视化、实践从数据到图形的过程。D3是一个根据数据操纵文档的JavaScript库[2],其全称Data-Driven Documents强调了这一点。D3的功能不止于做可视化,Documents代表可以在浏览器中展现的一切,包括HTML、SVG,根据数据操纵DOM(Document Object Model)可实现非常多的效果,但通常大家通常用D3来将数据映射为可视图形。

作为O‘REILLY动物书系列之一,《数据可视化实战》这本书语言简练逻辑性强、例子通俗易懂,200多页较全面地教了D3可视化的各种用法,由浅入深讲了使用D3的基本技术、数据绑定、比例尺、数轴及过渡等关键内容,本书很好地从数据角度切入绘图的框架和细节,不过值得说的是书标题写了交互(Interactive)但正文关于交互的篇幅并不长,只占一章。

本书思维导图简要版

D3技术基础

D3操作的是Web上的文档,可以便捷快速地向全世界发布可视化作品,对操作系统和设备的依赖很低。

D3库的功能和特点:

•将数据和DOM绑定在一起、图形随着数据变化;•数据转换和绘制独立;不是提供Pie()这类函数绘图而是将数据转换成饼图数据,再按需绘图。像面粉可以做出各种糕点而不是直接提供面条;•擅长矢量图形,缩放不损失图形精度,不擅长位图和瓦片,不擅长探索型可视化;•作为HTML文档,不隐藏原始数据,如果不想共享数据,为什么还要将它们可视化呢?

D3本质上还是JavaScript,这意味着我们可以用原生JavaScript代码实现讲到的所有功能,但D3对作了很好的封装,大大减轻了做可视化的工作量并应对各种需求。用D3做可视化的代码框架如下:

代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">
 <head>
 <meta charset="utf-8">
 <title>d3可视化代码框架</title>
 <script type="text/javascript" src="./d3/d3.min.js"></script>
 <!--直接引入在线的d3库:<script src="https://d3js.org/d3.v5.min.js"></script>
 -->
 </head>
 <body>
 <script type="text/javascript">
     // D3 代码部分
     d3.select("body").append("p").text("hello world!");
</script>
 </body>
</html>

来细看这段代码,除d3.select("body")...句外,都是通用的HTML代码,划分了层次结构,发挥功能的d3代码在块里。这段d3脚本代码的作用是在html的body元素里加入一个文本段落(<p></p>),并把文本内容hello world!添加给这个段落。可以总结下D3可视化的基本步骤如下:

•创建新元素并绑定数据(html的元素可理解为划定区域和声明类型的闭合标签,如p表示其是一个段落,是段落就可以有段落文本、长宽、id等属性和标识)•设置相应元素的可视属性,将数据值映射为元素大小、颜色、位置等可视属性;•对元素进行排列和变换,还有响应交互;

D3那句链式调用了.select()、append()等,也可以用中间变量承接,写成:

代码语言:javascript
复制
//拆成多个语句的写法:
var body = d3.select("body");
var p = body.append("p");
p.text("hello world!");

从原html文档到效果html

SVG

基于HTML文档的可视化基本都使用canvas或svg元素作为数据到图形的映射容器。D3也可以直接操作div或其他原生HTML元素来绘图,但总是略显笨重,且容易出现浏览器间不一致的问题。而用 SVG就更可靠,图形效果更一致,且绘图速度更快。SVG(Scalable Vector Graphics,可伸缩矢量图形)是一种基于XML标签来表示图形的文本。SVG 元素可以理解为能在上面绘制各种形状的画布。一个基础的svg示例如下,表示一个半径为20像素的圆形。

代码语言:javascript
复制
<svg width="500" height="50">
    <circle cx="200" cy="30" r="20" />
</svg>

在SVG的预定义元素里,有6种基本元素rect(矩形)、circle(圆形)、ellipse(椭圆)、line(线段)、polyline(折线)、polygon(多边形)和功能强大的path(路径),在SVG里也可以添加text(文本)元素。

和一些编程语言的坐标系统一样,基于像素的坐标系统的原点位于画布的左上角。增大 x 的值,图形会向右移动;增大 y 值,图形会向下移动。

元素添加与数据绑定

从前面的代码框架及D3可视化基本步骤可以看出,用D3将数据变成图形首先需要选定元素并添加SVG元素(如果html代码已经有了需要的<svg/>元素则只需选定该SVG元素)。d3的select()方法传入一个 CSS 选择符,返回DOM 中匹配的第一个元素的引用。典型用法如下:

•d3.select("body") ; //选择body元素;• d3.select("#apple"); //选择id为apple的元素;例如会匹配上<p id="apple">p01</p>• d3.select(".apple"); //选择class为apple的元素;会匹配上<p class="apple">p02</p>

如果想获得所有满足条件的元素,用selectAll()方法,典型写法同上。

我们在选择了需要操作的svg元素后,需要添加rect(矩形)等图形,用append()方法添加元素,insert()方法在所选元素前添加一个元素。用remove()方法在DOM中删除元素。通过attr()给所选元素添加属性。

通过datum(val)将数据val绑定到选中的所有元素。通过data(vals[,key])绑定数组vals中的每一项到选中的元素,key是一个用于指定绑定规则的函数。

代码语言:javascript
复制
var dataset = [ 5, 10, 15, 20, 25 ];
d3.select("body").selectAll("svg")
     .data(dataset)
     .enter()
     .append("svg")
     .attr("class",'bar')
     .style("background-color","#1EAFAE")
     .attr("width",50)
     .attr("height",function(d){return d*10 +"px";});

数据绑定

通过d3.csv("food.csv", function(data) {dataset=data;})可以读取本地的csv文件数据进行使用,这是写JavaScript代码很常用的写法。

代码语言:javascript
复制
d3.csv("bar-data.csv", function(data) {
      d3.select("body").selectAll("svg")
         .data(data)
         .enter()
         .append("svg")
         .style("background-color","#1EAFAE")
         .attr("width",50)
         .attr("height",function(d){return d*10 +"px";});
});

读取json文件的接口也类似,通过d3.json("food.json", function(data) {})来进行json文件的处理。

前面通过append()、attr()、style()等接口只是将数据映射为图形,离可视化图像还有些差距。比如我们需要有标识数据大小的数轴、标题、坐标轴标签等。标题通过text来绘制,图形颜色等通过style设置,数轴(坐标轴)可以拆解为线段+文本的组合,可以通过svg的line和text来画,需要注意的是坐标原点的位置以及y轴方向的问题。实际上d3提供了绘制坐标轴的接口,省去了很多工作量。在D3的v5版本中,通过d3.axisBottom(scale)绘制x轴(水平方向)、d3.axisLeft(scale)绘制y坐标轴。书中的v3版本使用的是 xAxis = d3.svg.axis().scale(xScale).orient("bottom");

基于以上方法绘制一个柱状图如下:

比例尺

对数据进行可视化时,我们可以直接把数据值映射为像素值,但是如果数值过小或过大直接用像素得到的图形就很难看。例如不能值是10000就绘制1万像素长的矩形。我们用比例尺(scale)来解决这个问题。从数据到屏幕图形的像素有一个数据变换的过程,在输入值范围(值域)不确定的情况,我们限定输出的范围,这就是比例尺的作用。

D3 提供了比例尺函数生成器。var scale = d3.scale.linear().domain([100, 500]).range([0, 100]);比例尺scale将输入数据从[100,500]输出的时候限制在[0,100]之间。D3不仅提供了线性比例尺可用,还有序数比例尺(实现{1:'r',2:'b',3:'g'})、对数比例尺、平方根比例尺等。上面绘制数轴的时候也直接用到了线性比例尺。

关于D3,可以继续深入学习内容参考如下:

交互:通过绑定事件监听器和定义行为实现图形和键鼠的交互;•过渡动画:同样通过事件监听和缓动实现过渡效果和数据更新;•各种布局:通过饼图布局实现柱状图变旭日图、力导向布局绘制人物关系图谱。

交互效果示例

D3可视化效果深入绘制

D3官网https://d3js.org/上有丰富的图形实例和最新的API,本书中的代码是基于d3.v3.js的API,目前2020年d3的版本已经更新到v5了,有部分API有变动,书中的部分代码直接运行会报错,因此遇到问题先在官网搜索是很好的习惯。

后续会基于这本书用6篇文章详细介绍和实践D3可视化,希望能写得容易实践且有深度。希望与你一同进步。

《数据可视化实战》这本书的读书笔记思维导图如上。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-04-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 蛰虫始航 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • D3技术基础
  • SVG
  • 元素添加与数据绑定
  • 比例尺
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档