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 ...
随机推荐
- SQL Server性能监控常用语句
.查找目前SQL Server所执行的SQL语法,并展示资源情况: SELECT s2.dbid , DB_NAME(s2.dbid) AS [数据库名] , --s1.sql_handle , ( ...
- 【Kafka】Producer配置
名称 描述 类型 默认值 bootstrap.servers kafka集群地址,ip+端口,以逗号隔开.不管这边配置的是什么服务器,客户端会使用所有的服务器.配置的列表只会影响初始发现所有主机.配置 ...
- IO流(三)其他流与File类
1:其他的流 1: DataOutputStream ;多了一些操作基本数据类型的功能 DataInputStream:读取文件. 用DataOutputStream流写进去的数据,就用DataInp ...
- C#中的委托 Delegate(委托 也叫代表,代表一类方法)
1. 委托类似与 C或C++中的函数指针,但委托是 面向对象的,并且是类型安全的 详情可查看官方文档:https://msdn.microsoft.com/en-us/library/ms173172 ...
- mvn pom
使用本地指定目录下jar包 <dependency> <groupId>com.myself.abc</groupId> <artifactId>sam ...
- 定时IIS任务自动停止及解决办法
---恢复内容开始--- 操作系统:WinServer2008 R2 IIS版本:IIS7.0 目的:利用IIS挂载服务,定时或循环作业 症状:在网站的Global.asax.cs文件的Applica ...
- VSCode基本配置
功能:保存时自动按ESLint规范格式化代码 + stylus配置(需安装Manta's Stylus Supremacy插件) { "editor.fontSize": 18, ...
- PHP调用百度api生成短网址&根据短网址恢复长网址
接口api文档地址:http://dwz.cn/#/apidoc?_k=i9ev5p 代码demo header("Content-type: text/html; charset=utf- ...
- 六、curator recipes之屏障barrier
简介 curator针对分布式场景实现了分布式屏障:barrier.我们在分布式系统中可以使用barrier去阻塞进程,知道某个条件被触发.其实跟Java多线程的barrier是一样的. 例如:当两个 ...
- 十六、Condition等待通知
一.简介 我们可以使用syncronized和wait,notify实现等待通知.而syncronized的高级实现Lock,也可以实现等待通知,需要构造Condition的实例对象. JDK文档:h ...