《数据可视化实战:使用D3设计交互式图表》学习笔记
第1-4章
1、D3:Data-Driven Documents(数据驱动的文档)。D3扮演的是一个驱动程序的角色,因为它联系着数据和文档。
2、D3最擅长处理矢量图形(SVG图或GeoJSon数据),矢量图是由点、直线和曲线,即数据方程式定义的,因此可以随意放大或缩小而不会失真。而位图由像素构成,很难在放大或缩小时做到不失真。
3、D3代码在客户端执行,即在用户浏览器而不是WEB服务器中执行,因此你想要可视化的数据必须发送到客户端。
4、DOM(Document Object Model,文档对象模型)
它是HTML标签的层次结构。浏览器通过解析DOM来操作页面内容。编码的人在实现可视化时,最关心的是DOM。因为我们的代码必须在DOM层次中寻找元素,然后为它们应用样式和行为。
5、SVG(Scalable Vector Graphics,可伸缩矢量图形)
在学习绘图之前,首先要创建SVG元素。可以把SVG元素想象成一个在上面作画的画布。至少要给新SVG元素指定width和height值。
第5章 数据
1、D3可以使用的数据:.txt文件、.csv逗号分割值文件,.json JSON文档。
注意CSV文件中每个值都是以字符串形式保存的。
2、
d3.select("body").append("p").text("New paragraph!")
- .select(“body”):向select()方法传入一个CSS选择符作为输入,它就会返回一个对DOM中匹配的第一个元素的引用。如果想取得多个元素,可以使用selectAll()方法。在这里取得文档的body元素,然后把它的引用交给调用链中的下一个方法。
- .append(“p”)
append()会创建一个你指定的新DOM元素,然后将它追加到调用它的元素末尾,作为调用它的子元素。这里创建了一个p元素,因为调用该方法的是body,所以就是在body元素内部追加一个p元素。最后,append()把刚创建的新元素的引用交给下一个方法。 - .text(“New paragraph!”)
text()接受一个字符串,把它插入到当前元素的开始和结束标签之间。如果标签间原来有内容,原来的内容会被覆盖。因为上一个方法传递过来一个p元素,因此这里就会把文本插入到< p >和< /p >之间。 - 不用连缀的写法
let body = d3.select("body");
let p = body.append("p");
p.text("New paragraph!");
3、数据必须绑定到页面的元素上才能可视化。所以我们先创建新的页面元素,然后再把数据绑定到这些元素上。
要通过D3的selection.data()方法把数据绑定到DOM元素,需具备两个条件:
- 数据
- 选中的DOM元素。
(1)加载CSV数据
使用d3.csv()方法。
d3.csv("food.csv",function(data){
console.log(data);
});
csv()方法接受两个参数,表示CSV文件路径的字符串和用作回调函数的匿名函数。回调函数只有在把CSV文件加载到内存之后才会执行,因此确定,在调用这个函数时,d3.csv()已经把数据加载完毕。回调函数执行时,会接收到加载和解析后的CSV数据data(什么名称无所谓,因为是匿名函数),在此例中,回调函数只是把接收到的数组数据输出到了控制台。(console.log(data)表示输出到控制台)。
注意:
- d3.csv()是一个异步方法,即在它加载数据的同时,其他JS代码会照样执行。
- 回调函数无论是否成功加载数据文件,都会执行。
4、enter()方法
let dataset = [5,10,15,20,25];
d3.select("body").selectAll("p")
.data(dataset)
.enter()
.append("p")
.text("New paragraph!");
- d3.select(“body”)
选择DOM中的body元素,把它交给连缀方法中的下一个方法。 - selectAll(“p”)
选择DOM中的所有段落。因为还没有段落,所以返回空元素,可以认为这个空元素代表马上就会创建的段落。 - data(dataset)
解析并数出数据值。因为dataset数组中有5个值,因而此后的所有方法都将执行五遍,每次针对一个值。 - .enter()
分析当前选择的DOM元素和传给它的数据,如果数据值比对应的DOM元素多,就创建一个新的占位元素,然后把这个新占位元素的引用交给链中的下一个方法。 - .append(“p”)
取得由enter()创建的空占位元素,并把一个p元素追加到相应的DOM中。之后把它创建的元素交给链中的下一个方法。 - .text(“New paragraph!”)
取得新创建的p元素,插入文本值。
此时,已经读取、解析了数据,并将数据绑定到了在DOM中创建的p元素上。控制台是确认数据绑定是否正确的一个工具。D3绑定的数据没有出现在DOM中,而是作为该元素的__data__属性保存在内存中。
5、data()方法
let dataset = [5,10,15,20,25];
d3.select("body").selectAll("p")
.data(dataset)
.enter()
.append("p")
.text(function(d){
return d;
})
在连缀方法中,只要调用data()了,就可以随时创建一个接收d为输入的匿名函数。与当前元素对应,方法data()确保每个d都会被赋予原始数据集中的一个值。
不能直接传入d,如果不把d封装在匿名函数里,d就没有值。没有匿名函数及其接收数据值的参数d,D3将无法把当前数据值传进来。
6、自定义函数
匿名函数(anonymous function):没有名字的函数
命名函数(named function):把函数保存在一个变量中,有名字的函数
命名函数实例:
let doSomething = function(){
//代码
};
使用D3的过程会写大量匿名函数。
7、attr()和style()可以分别用来设置取得的元素的HTML属性和CSS属性。
给某个元素添加一个bar类:
.attr("class","bar");
添加CSS属性:
style()方法执行的结果等价于在HTML的style属性中直接写入CSS规则。
d3.select("body").selectAll("p")
.data(dataset)
.enter()
.append("p")
.text(function(d) {
return "I can count up to " + d;
})
.style("color", function(d) {
if (d > 15) { //Threshold of 15
return "red";
} else {
return "black";
}
});
8、classed()方法
此方法用于快速地添加或删除元素的类。
//添加类
.classed("bar",true)
//删除类
.classed("bar",false)