2.使用时间范围尺
通常,我们进行分析的数据集,是与时间和日期相关的,因此,D3提供了内置的时间尺度来执行这种类型的映射。在这一节中我们就将学习如何使用D3的时间尺度。
准备好你的编辑器,输入如下代码
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Time Scale</title> <link rel="stylesheet" type="text/css" href="styles.css"/> <script type="text/javascript" src="http://d3js.org/d3.v3.min.js"></script> </head> <body> <div id="time" class="clear"> <span>Linear Time Progression<br></span> <span>Mapping [01/01/2013, 12/31/2013] to [0, 1200]<br></span> </div> <script type="text/javascript"> var start = new Date(2013, 0, 1), // <-A end = new Date(2013, 11, 31), range = [0, 1200], time = d3.time.scale().domain([start, end]) // <-B .rangeRound(range), // <-C max = 12, data = []; for (var i = 0; i < max; ++i){ // <-D var date = new Date(start.getTime()); date.setMonth(start.getMonth() + i); data.push(date); } function render(data, scale, selector) { // <-E d3.select(selector).selectAll("div.fixed-cell") .data(data) .enter() .append("div").classed("fixed-cell", true); d3.select(selector).selectAll("div.fixed-cell") .data(data) .exit().remove(); d3.select(selector).selectAll("div.fixed-cell") .data(data) .style("margin-left", function(d){ // <-F return scale(d) + "px"; }) .html(function (d) { // <-G var format = d3.time.format("%x"); // <-H return format(d) + "<br>" + scale(d) + "px"; }); } render(data, time, "#time"); </script> </body> </html>用浏览器运行该示例会得到如下的结果:
我们来看看这段代码是如何工作的,在这段代码中,我们在A处定义了从2013年1月1日到2013年12月31日的时间范围。
var start = new Date(2013, 0, 1), // <-A
end = new Date(2013, 11, 31),
range = [0, 1200],
time = d3.time.scale().domain([start, end]) // <-B
.rangeRound(range), // <-C
提示:在javascript时间对象中,月份是从0开始计算,日期是从1开始计算,所以我们的代码new Date(2013, 0, 1),new Date(2013, 11, 31)分别代表了2013年1月1日和2013年12月31日。
这个范围是用于创建一个D3的时间尺度,在代码B行用d3.time.scale()方法,和定量范围尺一样,时间范围尺同样支持单独的域和范围的界定,用来映射日期和时间的数据点到可视化的对象范围。在这个例子中,我们设置范围为[0,1200],这有效的定义了从2013年1月1日到2013年12月31日任意时间范围和数字0到1200的一个映射。
当时间尺度定义后,我们可以通过调用时间比例尺函数来映射任意的时间对象,比如time(new Date(2013,4,1))将返回395,time(new Date(2013,11,15))将返回1147. 等等。
在代码D行,我们创建一个12个月的时间数组
for (var i = 0; i < max; ++i){ // <-D
var date = new Date(start.getTime());
date.setMonth(start.getMonth() + i);
data.push(date);
}
然后在E行,我们使用render函数创建了12个div来分别代表12个月份。横向布局12个div。在F行执行时间比例尺函数来完成月份和数字间的映射,然后将映射的数值来设置代表每个月份的div的margin-left。G行用来生成标签,为了将javascript的时间对象生成人们可读的字符串,我们使用D3的时间格式化函数在H行处。D3拥有强大且灵活的时间格式库,在处理时间对象的时候非常灵活有用。
这里有一些常用的D3时间格式化模式
%a:这是星期的名称缩写。
%A: 这是星期的全称。
%b:这是月份名称的缩写。
%B:这是月份名称的全称。
%d:这是0填充的一个月日期的十进制数[01,31]。
%e: 这是无填充的一个月日期的十进制数[1,31]。
%H:这是0填充的24小时的十进制数[00,23]。
%I:这是12小时的十进制[01,12]。
%j:这是一年天数的十进制数[001,366]。
%m:这是12个月份的十进制数[01,12]。
%M:这是表示分钟的十进制数[01,59]。
%L: 这是表示毫秒的十进制数[000,999]。
%p:这是使用AM或PM。
%S:这是表示秒的十进制数[0,61]。
%x:以“月/日/年”格式现实日期。
%X:以“时/分/秒”格式现实时间。
%y:这是年份显示后两位的十进制[00,99]。
%Y:这是年份全部显示的十进制。
想了解全部的D3时间格式化库可参考链接https://github.com/mbostock/d3/wiki/Time-Formatting#format。