d3js data joins深入理解
Data joins
给定一个数据数组和一个 D3 selection 我们就可以attach或者说是'join'数组中的每个数据到selection中的每个元素上。
这将使得我们的数据和可视化元素之间建立紧密的联系并实现可视化成为可能。
比如如果我们有以下SVG的circles:
<circle r="40" />
<circle r="40" cx="120" />
<circle r="40" cx="240" />
<circle r="40" cx="360" />
<circle r="40" cx="480" />
和下面的data数组:
var scores = [
{
"name": "Andy",
"score": 25
},
{
"name": "Beth",
"score": 39
},
{
"name": "Craig",
"score": 42
},
{
"name": "Diane",
"score": 35
},
{
"name": "Evelyn",
"score": 48
}
]
那么我们就可以选中这些circles并且join data到这个selection:
d3.selectAll('circle')
.data(scores);
随后我们就可以对这个selection中的元素来设置相应属性为绑定的数据
d3.selectAll('circle')
.attr('r', function(d) {
return d.score;
});
上面的代码就将每个圆的半径设置为每个人的score值的大小。(实际使用中,我们往往还会用到scaleSqrt比例尺,因为分数大小和可视化的半径大小往往需要一个映射!)

从这个形象化的结果,我们就实现了数据的可视化:score值越大,圆的半径就越大,因此只要看到圆大就知道其分数高!
Making a data join
var myData = [ 10, 40, 20, 30 ];
var s = d3.selectAll('circle');
s.data(myData);
数组可以包含任何类型的数据,比如对象数组:
var cities = [
{ name: 'London', population: 8674000},
{ name: 'New York', population: 8406000},
{ name: 'Sydney', population: 4293000}
];
var s = d3.selectAll('circle');
s.data(cities);
Data-driven modification of elements
d3.selectAll('circle')
.attr('r', function(d) {
return d;
});
对每个selection中的element, d3都会调用.attr()函数, 传入该element的joined data d. 而上面匿名函数的返回值作为r的值设定到该元素中.
再比如以下elements:
<circle />
<circle />
<circle />
<circle />
<circle />
和如下数据
var myData = [ 10, 40, 20, 30, 50 ];
我们执行一下data join:
var s = d3.selectAll('circle');
// Do the join
s.data(myData);
s.attr('r', function(d) {
return d;
});
传入 .attr() 的匿名函数将被调用 5 次 (selection中的每一个元素调用一次). 第一次调用时d 是10 因此第一个circle的r设置为10. 第二次调用时为40 因此第二个circle的r设置为40...
我们也可以对d做任何其他处理之后再返回,比如
s.attr('r', function(d) {
return 2 * d;
});
再比如,如果元素绑定的数据大于40,我们则给该元素添加一个css类,以便更改这类元素的样式。
s.classed('high', function(d) {
return d >= 40; // returns true or false
});
最后我们来使用 i 参数来设置其cx的位置:
s.attr('cx', function(d, i) {
return i * 120;
});
总结如下:
var myData = [ 10, 40, 20, 30, 50 ];
var s = d3.selectAll('circle');
// Do the data join
s.data(myData);
// Modify the selected elements
s.attr('r', function(d) {
return d;
})
.classed('high', function(d) {
return d >= 40;
})
.attr('cx', function(d, i) {
return i * 120;
});
Arrays of objects
var cities = [
{ name: 'London', population: 8674000},
{ name: 'New York', population: 8406000},
{ name: 'Sydney', population: 4293000},
{ name: 'Paris', population: 2244000},
{ name: 'Beijing', population: 11510000}
];
var s = d3.selectAll('circle');
s.data(cities);
这时当我们根据joined data来修改元素属性时,d 将代表的是joined object. 这样对第一个元素,其 d 将是 { name: 'London', population: 8674000}.
我们再来根据每个城市的population设定circle的半径大小:
s.attr('r', function(d) {
var scaleFactor = 0.000005;
return d.population * scaleFactor;
})
.attr('cx', function(d, i) {
return i * 120;
});
当然,我们并不限于修改circle元素,加入我们还有rect和text元素,我们同样可以使用该data join并且设定这些元素的属性:
var cities = [
{ name: 'London', population: 8674000},
{ name: 'New York', population: 8406000},
{ name: 'Sydney', population: 4293000},
{ name: 'Paris', population: 2244000},
{ name: 'Beijing', population: 11510000}
];
// Join cities to rect elements and modify height, width and position
d3.selectAll('rect')
.data(cities)
.attr('height', 19)
.attr('width', function(d) {
var scaleFactor = 0.00004;
return d.population * scaleFactor;
})
.attr('y', function(d, i) {
return i * 20;
})
// Join cities to text elements and modify content and position
d3.selectAll('text')
.data(cities)
.attr('y', function(d, i) {
return i * 20 + 13;
})
.attr('x', -4)
.text(function(d) {
return d.name;
});
Under the hood
当d3执行data join时,d3将对每个dom元素增加一个attribute: __data__,并且将对应的data赋值给该属性。实际上,如果我们需要设置其他额外的数据的话,也可以在.each函数中通过.attr('custom_attr','data')来添加并且在后面使用。

使用这种方式来检查是否有绑定好的数据,在需要调试代码行为是否符合预期时是非常有用的。
如果我们的数组长度大于或者小鱼对应的selection元素将会发生什么?
到目前为止,数据数组的长度和元素的个数是相同的。往往现实并非如此,这时我们就需要了解enter和exit的概念了,我们在另外一篇博客中描述。
What’s .datum for?
在有些情况下, (比如当处理地图相关的可视化时 geographic visualisations) ,我们可能需要给一个只含一个元素的selection绑定一个single data,比如:
var featureCollection = {type: 'FeatureCollection', features: features};
d3.select('path#my-map')
.datum(featureCollection);
这将添加一个 __data__ attribute 到元素上并且 assigns the joined data (featureCollection )到这个元素上。可以查看 geographic visualisations
大多数情况下.data用于data join, .datum用于特定场景。
d3js data joins深入理解的更多相关文章
- 【wpf】Path画扇形以及Path的Data属性的理解
<Path x:Name="PathFillColor" Fill="{TemplateBinding Property=Button.Background}&qu ...
- d3js selections深入理解
D3 selections选择DOM元素以便可以对这些dom元素做相应的操作,比如:更改其style,修改其属性,执行data-join操作,或者插入.删除相应elements 比如,如果给定5个ci ...
- 学习Hadoop整体理解
HDFS是Hadoop的核心模块之一,围绕HDFS是什么.HDFS的设计思想和HDFS的体系结构三方面来介绍. Hadoop的设计思想受到Google公司的GFS设计思想的启示,基于一种开源的理念实现 ...
- Core Data(数据持久化)
Core Data可能是OS X和iOS中最容易被误解的框架之一了.为了帮助大家理解,我们将快速研究Core Data,来看一下它是关于什么的.为了正确使用Core Data, 有必要理解其概念.几乎 ...
- digitalocean解释:private networking和user data、IPv6是什么意思
digitalocean vps后台新建droplet的时候,底部会有available settings,里面有四个选项,大多数用户不懂啥意思,我今天解释下: Private Networking ...
- jQuery.prop , jQuery.attr ,jQuery.data
理一下这几个概念吧.根据jquery官网. jquery.prop 获取匹配的元素中第一个元素特定的属性值,或者是设置多个元素的属性值. 有4个重载. .prop(propertyName) 获取属性 ...
- JPA、Hibernate、Spring data jpa之间的关系,终于明白了
什么么是JPA? 全称Java Persistence API,可以通过注解或者XML描述[对象-关系表]之间的映射关系,并将实体对象持久化到数据库中. 为我们提供了: 1)ORM映射元数据:JPA支 ...
- Spring Data JPA、MyBatis还有Hibernate有什么区别
原文:https://www.imooc.com/article/19754?block_id=tuijian_wz Spring Data JPA.MyBatis还有Hibernate有什么区别 2 ...
- d3js enter/exit深入了解
在 Data joins 章节我们演示了当data和dom element个数相同时的情况 <div id="content"> <div></div ...
随机推荐
- Mac 10.12安装PDF浏览工具Foxit Reader
说明:永久没费的跨平台PDF浏览工具. 下载: (链接: https://pan.baidu.com/s/1pLEAoXH密码: is5j)
- ToolkitScriptManager vs. ScriptManager 关于“只能向页面中添加 ScriptManager 的一个实例”讨论
在使用ASP.NET设计AJAX功能网页时,需要首先声明ToolkitScriptManager或者ScriptManager控件,这些全局的脚本核心控制,然后才能使用众多的AJAX控件.如果没有创建 ...
- (转)Centos7上部署openstack ocata配置详解
原文:http://www.cnblogs.com/yaohong/p/7601470.html 随笔-124 文章-2 评论-82 Centos7上部署openstack ocata配置详解 ...
- sysv-rc-conf介绍
sysv-rc-conf简介 sysv-rc-conf是一个强大的服务管理程序,Ubuntu运行级别Linux 系统任何时候都运行在一个指定的运行级上,不同的运行级的程序和服务都不同,所要完成的工作和 ...
- SecureCRTPortable的安装和使用(图文详解)
不多说,直接上干货! 玩玩这个远程连接软件,是个绿色软件. 别人已经做好了的. 解压之后, 下面,软件展示下, 这会默认去打开, 为了,方便,使用,放到桌面,作为快捷方式 成功 欢迎大家,加入我的微信 ...
- 数据库~Mysql里的Explain说明
对于mysql的执行计划可以在select前添加Explain来实现,它可以告诉我们你的语句性能如何. 下面是对explain的具体说明,也都是官方的,以后进行参考. id SELECT识别符.这是S ...
- C 标准库 - ctype.h之isalnum使用
isalnum int isalnum ( int c ); Checks whether c is either a decimal digit or an uppercase or lowerca ...
- DFT,可测试性设计--概念理解
工程会接触DFT.需要了解DFT知识,但不需要深入. 三种基本的测试(概念来自参考文档): 1. 边界扫描测试:Boundary Scan Test: 测试目标是IO-PAD,利用JTAG接口互连以方 ...
- Nginx教程(7) 正向代理与反向代理【总结】
1.前言 最近工作中用到反向代理,发现网络代理的玩法还真不少,网络背后有很多需要去学习.而在此之前仅仅使用了过代理软件,曾经为了访问google,使用了代理软件,需要在浏览器中配置代理的地址.我只知道 ...
- CNN理解与实现
CNN理解与实现 组成部分 Convolution Layer Pool Layer: Max-pooling layer Average-pooling layer Full Connected(F ...