一个初学者的指南,使用D3做数据绑定
D3.js 是个强大的数据可视化库,可以做出惊艳的图表。比如:气泡图,线图和条形图--只需要很少行的代码
随着初学者对JavaScript的理解,可以将数组或者对象转换成一个五彩缤纷的显示效果。然而,每一个初学者的比较纠结的是一开始理解如何将数据绑定在实际的DOM元素上。这就是我们所知道的“数据绑定”或者叫“数据连接”。这是一个重要的处理,因为这个整个过程的第一步!
非常直观的,你可能希望使用一个 for() 循环,循环每一项数据并且创建一个元素,像这样:
var data = [{x: 100,y: 100},{x: 200,y: 200},{x: 300,y: 300}]
for(var i = 0; i< data.length;i++){
svg.append("circle")
.attr("cx",function(data){ return data[i].x;})
.attr("cy",function(data){ return data[i].y;})
.attr("r",2.5);
}
但是,这并没有说如何让它工作,事实上,这里没有for()循环,下面的这个代码块将覆盖上面的功能:
var data = [{x: 100,y: 100},{x: 200,y: 200},{x: 300,y: 300}]
svg.selectAll("circle")
.data(data)
.enter().append("circle")
.attr("cx",function(data){ return data[i].x;})
.attr("cy",function(data){ return data[i].y;})
.attr("r",2.5);
这段代码会添加3个黑色的圆圈到你的SVG cancas,哇,这是因为D3使用了声明式编程,for()循环隐含在这个代码块里。
这篇文章将用于入门,所以我会将上面的代码块一行一行的解释,可以让你完全理解代码是如何运行的。我觉得可以将这个比喻为一个蔬菜种植园。当你读完这篇文章,你将可以建立一个基本的可视化视图,使用5到10行代码。
如果你想找一些关于这个概念更多的技术说明,可以去看D3文档或者Scott Murray的guide to binding
第一步:svg/地块
首先,你需要选择一个地方来画你的可视化试图。这就相当于你想找一块地方来种植。
var svg=d3.select("body")
.append("svg")
.attr("weight",‘800px‘)
.attr("height",‘800px‘);
你创建了一个800px * 800px的地块--这个"body"--一个你可以加入元素的地方。相当简单。
第二步:selectAll/挖洞
接下来,我们需要selectAll()语句来创建一个组,后面我们将用元素填充。想象一下,就像是在你的花园里挖洞。D3可以更新或者移除整个元素组,这是例子:
svg.selectAll("circle")
如果你没有添加任何的圆圈,那这个是正常的,请注意,"circle"是SVG specification中一个基本的形状,如果你添加了圆圈,你可以选择使用类名,像这样:
svg.selectAll(".circleClass")
这张图不是很准确,因为你的花园里可以有无数个洞。没有什么好的方式使用一张图合理的说明这块空地的数量。最重要的是你规划一块区域,放入你的数据元素。如果你想加入SVG“矩形”元素。你会在你花园的另外一部分添加。在代码里的这一点,你并不清楚你会添加多少元素。下面就让我们来弄清楚这个。
第三步:Data/种子
这是最重要的一部分。它决定了你将用于可视化的数据。在JavaScript里,你可以通过数组或者对象传递数据,在这一步,你"绑定"你的数据在DOM元素上,DOM元素的类型是你在selectAll()中所指定的。你可以像平时在JavaScript的方式引用数组或者对象的子项。在这个例子里,这里有三个子项在数组中,当我们写完如下代码,所以我们希望有三个DOM元素被添加:
var data = [{x: 100,y: 100},{x: 200,y: 200},{x: 300,y: 300}]
svg.selectAll("circle")
.data(data)
这很像选择一种特定类型的种子种在你的花园里。每个类型的种子都有一定的特性,并且我们知道这些种子的类型。
第四步:Enter/把种子放入洞里
.enter() 方法匹配selectAll语句中数组或者对象的子项数量,并且决定了你需要创建的元素的数量。你不再拥有一个无限土地。洞的数量现在匹配你想要种的植物的数量:
svg.selectAll("circle")
.data(data)
.enter()
在这个例子的代码中,有三个坑,种子是一种特定的类型(比如:土豆),这也决定了你的代码会自动迭代的次数(3次)
第五步:Append/植物的结构
.append()方法决定了你使用哪种SVG基本形状,尽管你有很多选项在selectAll()语句中,但在这一步你只有7种形状可以选择。selectAll()是为一组命名,append()是命名为实际的形状。
svg.selectAll("circle")
.data(data)
.enter().append("circle")
这跟你植物的结构很相似,你想要你的植物长成什么样子?如果你想长成番茄,你需要一个塔,不同的形状和不同的数据可视化是适用于不同的数据集。
简要说明如何访问数据
好了,现在你已经添加了3个圆圈的DOM元素,你选择了你的土地,挖了洞,种下了种子并且提供植物生长的结构。以下是如何选择每个圆圈的属性:
.attr("cx", function(d) { return d.x; })
.attr("cy", function(d) { return d.y; })
根据圆的规范,我们知道,可以通过SVG canvas 使用cx和cy来决定圆的位置,在上面的例子中,我们使用了function(d)去访问一开始的数组里的每一个子项,直到我们使用了.enter(),这个代码块会根据数组中的每一个元素运行一次,总共运行了三次。
这个d参数代表了数组中的每一个元素,比如:{x: 100, y: 100},如果参数的形式d,i,这个i就是数组的索引,当它是0的时候指的是数组中第一个元素,1时指的是第二个元素,以此类推。当你调用它时d.x,就是在查找每个元素的x属性,并把相应的值变成像素,在我们的例子中,是距离右边100个像素,现在你就是在使用平常所使用的Javascript!你可以使用if语句,调用function等等一些其他的。
结论
在你使用D3构建很酷的东西的时候,你需要理解你选择的将数据转换在DOM元素中的具体的方法,样式相比数据是比较简单的。添加文本跟添加形状特别相似,一旦你理解的数据这部分,你也会理解文本。
尽管你可能会D3的创造者添加了这样富有挑战性的概念在早期的学习过程,但是他们有好的理由这么做。D3是一个灵活的库,你可以接近自动的处理很多挑战,这个数据绑定结构可以帮助你完成复杂的操作,仅需要一两行代码,现在就去惊艳你的用户吧!