- D3
(Data-Driven Documents)是基于数据的文档操作JavaScript库,D3能够把数据和HTML、SVG、CSS结合起来,创造出可交互的数据图表。
- HTML
超文本标记语言(HyperText Markup Language)用于结构化网页内容。
<html> <head> <title>Page Title</title> </head> <body> <h1>Page Title</h1> <p>This is a really interesting paragraph.</p> </body> </html>
- DOM
文档对象模型(Document Object Model)指的是HTML的分层结构。
网页浏览器通过解析DOM来理解页面的内容。
- CSS
层叠样式表(Cascading Style Sheets)用于为HTML页面的图形表达设计样式。
CSS样式包括选择器(selectors)和规则(rules)。body { background-color: white; color: black; }
选择器指定应用样式的元素,例如:
h1:选择第1层标题
p:选择段落
.caption:选择class为caption的元素
#subnav:选ID为subnav的元素
规则是构成样式的内容,它是可累加的。例如
选择器和规则之间用大括号连接。color: pink; background-color: yellow; margin: 10px; padding: 25px;
D3使用CSS样式选择器来定位需要操作的元素。p { font-size: 12px; line-height: 14px; color: black; }
CSS规则可以直接放在网页的head中
或单独存于后缀为.css的外部文件中,然后在head中引用<head> <style type="text/css"> p { font-family: sans-serif; color: lime; } </style> </head>
<head> <link rel="stylesheet" href="style.css"> </head>
- JavaScript
JavaScript是一种动态脚本语言,它可以向浏览器发送命令,在页面加载完成之后再去修改网页内容。
脚本可以直接放在script标签下
或存于外部文件中,然后在HTML的某个位置上引用(一般是head)<body> <script type="text/javascript"> alert("Hello, world!"); </script> </body>
<head> <title>Page Title</title> <script type="text/javascript" src="myscript.js"></script> </head>
- 开发工具
Chrome中Ctrl+Shift+I
- SVG
D3最擅长用可缩放矢量图形(Scalable Vector Graphics, SVG)来渲染可视化效果。
SVG是一种基于文本的图像格式。意思是,你可以通过编写简单的标记式代码来设计一幅SVG图像,类似于用标签设计HTML。SVG代码可以直接用于HTML。
例如,一个圆
缩放网页时你可以发现它是平滑过渡的,因为它是矢量图,不是栅格图。<svg width="50" height="50"> <circle cx="25" cy="25" r="22" fill="blue" stroke="gray" stroke-width="2"/> </svg>
你并不是必须在D3中使用SVG,但是,SVG提供的大量的可视化效果,常规HTML元素根本无法实现。
- 建立D3工程
a. 下载D3
b. 本地目录
c. index.html内容project-folder/ d3/ d3.js d3.min.js(可选) index.html
d. 在目录下执行<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>D3 Test</title> <script type="text/javascript" src="d3/d3.js"></script> </head> <body> <script type="text/javascript"> // Your beautiful D3 code will go here </script> </body> </html>
python - m http.server 8888
- 调用D3
把script标签中注释的部分替换为:
a. select()方法用CSS选择器语法从DOM中选择了一个元素(body)d3.select("body").append("p").text("New paragraph!");
b. append()方法创建一个新的元素p,然后添加到所选元素的末尾
c. text()方法为新的空段落设置文本内容
- D3 API 文档
https://github.com/mbostock/d3/wiki/API-Reference
- 数据可视化是一个将数据映射为图形的过程。
通过D3,把输入数据绑定到DOM中的元素上。绑定就是把数据附着或联系到特定的元素上,然后可以应用映射规则引用这些数据的值。
使用selection.data()方法把数据绑定到DOM元素上。
D3支持处理不同类型的数据,支持任意数字,字符串或对象的数组,支持JSON,甚至提供一些内置方法加载CSV文件。
- 数据绑定
数组
绑定var dataset = [ 5, 10, 15, 20, 25 ];
.data(dataset) 对数据值进行计算和解析。有多少个值,通过此处的代码就会被执行多少次。d3.select("body").selectAll("p") .data(dataset) .enter() .append("p") .text("New paragraph!");
.enter() 为了生成新的绑定了数据的元素,必须使用enter()方法。此方法比较DOM元素和待处理数据个数。如果数据值的个数多于相应的DOM元素,则enter()方法会生成新的占位元素,在每个占位元素上进行余下的操作。每个占位元素都会被传递给链中的下一个方法。
.append("p") 接收由enter()选择的(新生成的)点位元素,然后在DOM中插入一个元素。新元素的引用会被传递给链中的下一个方法。
Console在Console标签查看所有标签为p的元素的信息
把最后一行改成console.log(d3.selectAll("p"))
会输出实际绑定的数据。因为每次调用data()方法都会生成一个接受d作为输入的匿名函数。对于每个当前元素,data()方法确保了d被设置为原始数据集中的对应值。.text(function(d) { return d; });
- 函数
function(input_value) { //Calculate something here return output_value; }
- style()
.style("color", "red");
.style("color", function(d) { if (d > 15) { //Threshold of 15 return "red"; } else { return "black"; } });
- div元素
<div style="display: inline-block; width: 20px; height: 75px; background-color: teal;"> </div>
<style type="text/css"> div.bar { display: inline-block; width: 20px; height: 75px; /* We'll override this later */ background-color: teal; } </style>
通过D3为每个元素增加类(class),应使用selection.attr()方法<div class="bar"></div>
.attr("class", "bar")
- classed()方法
从元素中快速的应用或删除类
.classed("bar", true)
- 设置5个柱状图
var dataset = [ 5, 10, 15, 20, 25 ]; d3.select("body").selectAll("div") .data(dataset) .enter() .append("div") .attr("class", "bar");
.style("height", function(d) { var barHeight = d * 5; //Scale up by factor of 5 return barHeight + "px"; });
- 一个html例子
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>D3 Test</title>
<script type="text/javascript" src="d3.js"></script>
<style type="text/css">
div.bar {
display: inline-block;
width: 20px;
height: 75px; /* We'll override this */
background-color: teal;
}
</style>
</head>
<body>
<script type="text/javascript">
var dataset = [23,42,66,75,8,23,67,33,22,32,7,8];
d3.select("body").selectAll("div")
.data(dataset)
.enter()
.append("div")
.attr("class", "bar")
.style("height", function(d){
var barHeight = d * 5;
return barHeight + "px";
});
</script>
</body>
</html>
- JavaScript的数组
var dataset = []; //Initialize empty array for (var i = 0; i < 25; i++) { //Loop 25 times var newNumber = Math.random() * 30; //New random number (0-30) dataset.push(newNumber); //Add new number to array }
- SVG
SVG元素是一个画布,类似于HTML的canvas元素。不指定宽高则充满。
左上角是坐标(0, 0)<svg width="500" height="50"> </svg>
rect
circle<rect x="0" y="0" width="500" height="50"/>
eclipse<circle cx="25" cy="25" r="20" fill="rgba(128, 0, 128, 1.0)"/>
line<ellipse cx="250" cy="25" rx="100" ry="25"/>
text<line x1="0" y1="0" x2="500" y2="50" stroke="black"/>
<text x="250" y="25" font-family="sans-serif" font-size="25" fill="gray">Easy-peasy</text>
- 画圆
<script type="text/javascript">
var dataset = [3,5,7,9];
d3.select("body").append("svg").selectAll("circle").data(dataset).enter().append("circle").
attr("cx", function(d,i){return (i*50) +50;}).attr("cy", 100).attr("r", function(d){return d;}).
attr("fill", "yellow").attr("stroke", "tomato").attr("stroke-width", function(d){return d/2});
</script>
- JavaScript的数组和字典
var fruits = [ { kind: "grape", color: "red", quantity: 12, tasty: true }, { kind: "kiwi", color: "brown", quantity: 98, tasty: true }, { kind: "banana", color: "yellow", quantity: 0, tasty: true } ];
- JSON
JavaScript Object Notation
JSON只不过是把数组组织成JavaScript对象的一种特定的语法。这种语法针对JavaScript和AJAX请求进行了优化,因而,在基于web的API中会看到很多JSON数组。相比于XML,JSON解析起来更快,也更容易。
JSON语法:和字典的区别就在于所有索引都用双引号包围起来,变成字符串。
var jsonFruit = { "kind": "grape", "color": "red", "quantity": 12, "tasty": true };
- GeoJSON
JSON是JavaScript对象的规范化,而GeoJSON是JSON对象的进一步规范化语法,针对地理数据进行了优化。所有的GeoJSON对象都是JSON对象,而所有的JSON对象都是JavaScript对象。
GeoJSON可以在地理空间中存储点(经纬坐标),它还可以存储形状(如线和多边形)和空间特征。
经度总是放在纬度前。var geodata = { "type": "FeatureCollection", "features": [ { "type": "Feature", "geometry": { "type": "Point", "coordinates": [ 150.1282427, -24.471803 ] }, "properties": { "type": "town" } } ] };
- 制作一个柱状图
<script type="text/javascript">
var dataset = new Array();
for(i=0; i<30; i++)
{
dataset[i] = Math.random() * 29 + 1;
}
d3.select("body").append("svg").selectAll("rect").data(dataset).enter().append("rect")
.attr("x", function(d,i){return i*10;})
.attr("y", function(d){return 40-d;})
.attr("width", 8)
.attr("height", function(d){return d+10;})
.attr("fill", function(d){return "rgb(0, " + Math.floor(d*8) +",0)";});
d3.select("body").select("svg").selectAll("text").data(dataset).enter().append("text")
.text(function(d){return Math.floor(d);})
.attr("x", function(d,i){return i*10+4;})
.attr("y", function(d){return 46-d;})
.attr("font-size", "6px")
.attr("fill", "orange")
.attr("text-anchor", "middle");
</script>
- 尺度
“尺度是把输入域映射为输出范围的函数。” —— Mike Bostock
归一化是根据可能的最小和最大值, 把数值映射到0到1之间的数的过程。
D3创建一个尺度
var scale = d3.scale.linear(); scale(2.5); //Returns 2.5
scale.domain([100,500]); //输入范围 scale.range([10,350]); //输出范围 - 取最大值
d3.max(dataset, function(d) { //Returns 480 return d[0]; //References first value in each sub-array });
- d3.scale.linear()其它方法
nice():把(range()函数指定)输入范围的边界映射至最近的”取整”的值上。例子,对于输入范围 [0.20147987687960267, 0.996679553296417],它的输出将是[0.2,1]。
rangeRound(): 用rangeRound()来替换range(),则尺度函数所有的输出将会映射至最近的”取整”值。
clamp(): 一个线性尺度函数默认允许返回输出范围之外的值。比如,如果给定一个输入范围之外的输入值,尺度函数的返回值就会跑到输出范围之外。通过对尺度函数调用.clamp(true),会强制所有的输出值都位于指定的输出范围之内。这表示,超过范围的输入值会被映射到输出范围的(最近的)端点上。
- D3的其它尺度
identity: 1:1尺度,主要用于像素值
sqrt: 平方根尺度
pow: 幂次尺度
log: 对数尺度
quantize: 输出为离散值的线性尺度,用于将数据归类的情况
quantile: 类似于quantize,不同的是输入也是离散值
ordinal: 有序尺度,输出为非数值的值(比如类别名称)。
- 坐标轴
D3学习笔记
最新推荐文章于 2024-07-18 10:23:58 发布