我的目的是,诠释100个d3.js的例子。
多是史上最细致的 。
Area Chart
是Basic Charts
里的第一个例子。
剖析
1
var margin = {top: 20, right: 20, bottom: 30, left: 50},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
地道的JavaScript代码。
起首定义上下左右margin
的值。然后以960和500作为全部图表(包含空缺部份)的宽和高,撤除空缺部份,算出图表实在的大小。这也就是x轴(width
)和y轴(height
)的长度。
2
var parseDate = d3.time.format("%d-%b-%y").parse;
运用了d3.time
的Time Formatting。它用来在时刻对象和字符串之间互相转换。%d-%b-%y
叫做specifier
,示意的是“24-Mar-08”这类时刻款式。parse
是一个函数,赋值给parseDate
变量,轻易今后的挪用。
整行代码的意义就是,把的一个函数赋给了parseDate
,这个函数可以把长得像“24-Mar-08”的字符串转换成时刻对象。
3
var x = d3.time.scale()
.range([0, width]);
var y = d3.scale.linear()
.range([height, 0]);
这两句都是和d3.scale
相干的,所以放在一同讲。先提出一个题目来诠释一下scale
是做什么的。
怎样从 0-100 映照到 0-1 ? 答案天然就是
0 -> 0
1 -> 0.01
2 -> 0.02
…
以此类推。那从 100-0 映照到 0-1 呢? 从 1-12 到 1月到12月 呢? 或许从 0 – 1 推断 男女呢? scale
就是做这个用的,它主要有三类:
数字 (0-1)
笔墨 (男女)
时刻 (月份)
而方才的例子中,0-100 叫做domain
,可以理解为输入的值域。0-1 叫做range
,就是输出的值域。
x
这个scale
就是时刻,它输出的值域会在0
到width
之间。y
这个scale
就是数字,它输出的值域会在height
到0
之间。注重,这里并没有设置domain
,也就是输入的值域。由于,输入值域固然要比及读取数据以后才会清楚明了。
所以,从这里看出,x
和y
的输出值域与width
和height
有亲昵的关联。天经地义的,它们以后肯定会被用作构图。
4
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(y)
.orient("left");
这两句看字面意义就可以了。它们和d3.svg.axis
相干,是在竖立坐标轴。xAxis
运用了上一段建立的scale
x
,同时指定了它的朝向是向下。意义是,程度的横轴,笔墨在轴的下面。以此类推,yAxis
运用了scale
y
,垂直的纵轴,笔墨在轴的左侧。
5
var area = d3.svg.area()
.x(function(d) { return x(d.date); })
.y0(height)
.y1(function(d) { return y(d.close); });
竖立了一个svg
的area
。地区 (area
) 的意义是,关于一个x
,y0
和y1
之间的部份示意此x掩盖的地区。
x
和y1
都接受了一个函数,函数的形参是d
。当衬着的时刻,d3.js
会把每一条数据都一一传进来。
为何y0
是height
,而y1
是d.close
?
关于某个的x
,y0
示意掩盖地区垂直方向的起始点,y1
示意停止点。从d3.js
的角度来讲,左上角为(0, 0),对这个点将会绘制(x
, y0
=height
)到(x, y1
=d.close
),也就是从图表的最底部往上画,画到d.close
。
6
var svg = d3.select("body").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
这部份比较简单,找到html
里的body
,在其末端加上一个svg
,而且指定了svg
的高度的宽度。末了在svg
里到场一个g
(group),而且留出margin的间隔。
7
d3.tsv("data.tsv", function (error, data) {
if (error) throw error;
读取数据的函数,数据源是tsv
(tab separated values)。当d3.js
读取而且处置惩罚完数据,会实行这个function(error, data)
这个callback。而数据会以数组的情势存放在形参data
内里.
8
data.forEach(function(d) {
d.date = parseDate(d.date);
d.close = +d.close;
});
既然data
是数组,那我们就对它的每个元素举行处置惩罚。
对date
运用之前保留下来的parseDate
函数,记不记得,它可以处置惩罚相似24-Mar-08
的字符串。
而close
仅仅是从字符串换成数字。
9
x.domain(d3.extent(data, function(d) { return d.date; }));
y.domain([0, d3.max(data, function(d) { return d.close; })]);
回想一下,方才的x
和y
作为scale
只设定了与绘图面积相干的range
(输出值域)。如今读完数据了,须要设置domain
(输入的值域)。d3.extent
是一个数组的辅佐函数,可以返回其最小值和最大值。
完成今后,x
scale
的映照是,[时刻最小值,时刻最大值] -> [0, width],也就是xAxis的最左和最右。y
scale
的映照是,[0,最大值] -> [height, 0],也就是yAxis的最低和最高。
10
末了几行比较无趣,一同说吧。
svg.append("path")
.datum(data)
.attr("class", "area")
.attr("d", area);
用途置惩罚好的数据竖立area
。唯一要说一说的是这个datum
,它平常用于静态的数据可视化。也就是说,假如这个元素不须要跟着数据的变化而变化,那末用datum
是适宜的。越发详细的诠释,或许是动态更新数据可视化的要领,拜见这里。
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
竖立x轴的g
——— g
是group
的意义。除了竖立的时刻用了之前的xAxis
,其他几行无非是加一些css class,然后下移到(0, height)位置,也就是图表的下方。
svg.append("g")
.attr("class", "y axis")
.call(yAxis)
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", ".71em")
.style("text-anchor", "end")
.text("Price ($)");
竖立y轴的group
,同时加一个笔墨,转90度,设定初始位置和偏移量,同时转变字体自身锚的位置(平常都以左上角为锚)。
参考:
1 https://github.com/mbostock/d3/wiki/Gallery#basic-charts
2 http://bl.ocks.org/mbostock/3883195
3 https://gist.github.com/hugolpz/824446bb2f9bc8cce607