解释!解释!(1) - Area Chart

我的目的是,诠释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就是时刻,它输出的值域会在0width之间。y这个scale就是数字,它输出的值域会在height0之间。注重,这里并没有设置domain,也就是输入的值域。由于,输入值域固然要比及读取数据以后才会清楚明了。

所以,从这里看出,xy的输出值域与widthheight有亲昵的关联。天经地义的,它们以后肯定会被用作构图。

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); });

竖立了一个svgarea。地区 (area) 的意义是,关于一个xy0y1之间的部份示意此x掩盖的地区。

xy1都接受了一个函数,函数的形参是d。当衬着的时刻,d3.js会把每一条数据都一一传进来。

为何y0height,而y1d.close?

关于某个的xy0示意掩盖地区垂直方向的起始点,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; })]);

回想一下,方才的xy作为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 ——— ggroup的意义。除了竖立的时刻用了之前的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

    原文作者:Shhh
    原文地址: https://segmentfault.com/a/1190000004684309
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞